एक सरणी का यादृच्छिक फेरबदल


232

मुझे निम्न एरे को बेतरतीब ढंग से फेरबदल करने की आवश्यकता है:

int[] solutionArray = {1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1};

क्या ऐसा करने के लिए कोई कार्य है?


5
यह वह SDK विधि है जिसे आप Collections.shuffle (Arrays.asList (array)) के लिए देख रहे हैं;
लुई होंग

2
@Louie नहीं, यह काम नहीं करता है। यही कारण है कि एक बन जाएगा List<int[]>युक्त एक प्रविष्टि। इसका उपयोग करने के तरीके के लिए मेरा उत्तर देखें Collections.shuffle()
डंकन जोन्स

2
वास्तव में मूल प्रश्न का उत्तर नहीं है, लेकिन गणित-गणित 3 पुस्तकालय से MathArrays.shuffle काम करता है।
सैंड्री

1
यह एक उत्तर को वारंट करने के लिए पर्याप्त विषय पर नहीं है, लेकिन मुझे "ग्राफिक्स रत्न" पुस्तक से एक बहुत अच्छा लेख याद है जिसने छद्म यादृच्छिक क्रम में एक सरणी को पार करने के बारे में बात की थी। मेरे मन में है कि वास्तव में पहली जगह में डेटा फेरबदल करने के लिए धड़कता है। सी-कार्यान्वयन यहाँ पाया गया है github.com/erich666/GraphicsGems/blob/master/gems/Dissolve.cn
Lennart Rolland

इसके अलावा इस संबंधित प्रश्न को देखें: stackoverflow.com/questions/2450954/…
पियरज़

जवाबों:


263

आदिम प्रकार की एक सरणी फेरबदल करने के लिए संग्रह का उपयोग करना ओवरकिल का एक सा है ...

फिशर-येट्स फेरबदल का उपयोग करके, फ़ंक्शन को स्वयं लागू करना काफी सरल है :

import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

class Test
{
  public static void main(String args[])
  {
    int[] solutionArray = { 1, 2, 3, 4, 5, 6, 16, 15, 14, 13, 12, 11 };

    shuffleArray(solutionArray);
    for (int i = 0; i < solutionArray.length; i++)
    {
      System.out.print(solutionArray[i] + " ");
    }
    System.out.println();
  }

  // Implementing Fisher–Yates shuffle
  static void shuffleArray(int[] ar)
  {
    // If running on Java 6 or older, use `new Random()` on RHS here
    Random rnd = ThreadLocalRandom.current();
    for (int i = ar.length - 1; i > 0; i--)
    {
      int index = rnd.nextInt(i + 1);
      // Simple swap
      int a = ar[index];
      ar[index] = ar[i];
      ar[i] = a;
    }
  }
}

26
अत्यधिक तुच्छ नाइटपिक, लेकिन आप println()इसके बजाय बस का उपयोग कर सकते हैं println("")। इरादे में स्पष्ट मुझे लगता है :)
कोवान

55
कलेक्शन.शफल (एरेस.सलिस्ट (सरणी)) का उपयोग करना बहुत बेहतर होगा; तो अपने आप को एक फेरबदल कर।
लुई होंग

21
@Louie Collections.shuffle(Arrays.asList(array))काम नहीं करता है, क्योंकि जैसा आपने सोचा था वैसा नहीं Arrays.asList(array)लौटाया । Collection<int[]>Collection<Integer>
एडम स्टेलमास्कज़ी

15
@exhuma क्योंकि यदि आपके पास सॉर्ट करने के लिए हजारों या लाखों आदिम मान हैं, तो हर एक को एक सॉर्ट करने के लिए रैप करना थोड़ा महंगा है, मेमोरी और सीपीयू दोनों में।
फीलो

14
यह वह जगह है नहीं फिशर-येट्स फेरबदल। इसे डर्स्टनफील्ड फेरबदल कहा जाता है । मूल फिशर-येट्स फेरबदल ओ (एन ^ 2) समय में चलता है जो बेहद धीमा है।
पचेरियर

164

यहाँ एक का उपयोग कर एक सरल तरीका है ArrayList:

List<Integer> solution = new ArrayList<>();
for (int i = 1; i <= 6; i++) {
    solution.add(i);
}
Collections.shuffle(solution);

1
आप बस खोज सकते हैंCollectons.shuffle(Arrays.asList(solutionArray));
FindOutIslamNow

@ टिटमोस तुम गलत हो। Arrays.asList मूल सरणी के चारों ओर घूमता है और इस प्रकार इसे संशोधित करके मूल सरणी को संशोधित करता है। इसलिए आप जोड़ या हटा नहीं सकते, क्योंकि सरणियाँ निश्चित आकार हैं।
नंद

@ और मुझे यकीन नहीं था कि मैं क्या सोच रहा था, लेकिन स्रोत कोड को देखकर, वास्तव में Arrays.asList पद्धति एक सरणी प्रदान करती है जो दिए गए सरणी द्वारा समर्थित है। इस पर ध्यान दिलाने के लिए धन्यवाद। मेरी पिछली टिप्पणी हटा दी गई (इसे संपादित नहीं किया जा सका)।
टिम्मोस

100

यहाँ एक काम कर रहा है और कुशल फिशर-येट्स फेरबदल सरणी समारोह:

private static void shuffleArray(int[] array)
{
    int index;
    Random random = new Random();
    for (int i = array.length - 1; i > 0; i--)
    {
        index = random.nextInt(i + 1);
        if (index != i)
        {
            array[index] ^= array[i];
            array[i] ^= array[index];
            array[index] ^= array[i];
        }
    }
}

या

private static void shuffleArray(int[] array)
{
    int index, temp;
    Random random = new Random();
    for (int i = array.length - 1; i > 0; i--)
    {
        index = random.nextInt(i + 1);
        temp = array[index];
        array[index] = array[i];
        array[i] = temp;
    }
}

1
वोट दिया गया क्योंकि मुझे एक ऐसे समाधान की ज़रूरत थी, जिसमें कलेक्शन ऑफ
इंटेगर

2
क्या दूसरे कार्यान्वयन में अपने स्वयं के सूचकांक के साथ स्वैप करने की क्षमता नहीं है? random.nextInt(int bound)विशेष है, लेकिन इसे i + 1तर्क के रूप में देना indexऔर iसंभावित रूप से समान होना चाहिए।
bmcentee148

21
@ bmcentee148 अपने आप में एक तत्व को स्वैप करना यादृच्छिक क्रम में अनुमेय है। इसे न समझने से पहेली कमजोर हो गई और एलन ट्यूरिंग को इसे क्रैक करने में सक्षम बनाया। en.wikipedia.org/wiki/…
एलेन स्पार्टस

4
xorचाल CPU रजिस्टरों की अदला-बदली जब सीपीयू कोई स्वैप अनुदेश है और वहाँ कोई मुक्त रजिस्टरों हैं के लिए महान है, लेकिन एक पाश अंदर सरणी तत्वों की अदला-बदली के लिए, मैं कोई लाभ नहीं दिख रहा। अस्थायी स्थानीय चर के लिए, उन्हें लूप के बाहर घोषित करने का कोई कारण नहीं है।
होल्गर

1
tempलूप के बाहर चर घोषित करने के लिए यह थोड़ा अधिक कुशल है । XORचाल एक का उपयोग कर से अधिक तेजी से होना चाहिए tempचर लेकिन एक ही तरीका है यकीन है कि यह एक बेंचमार्क परीक्षण प्रदर्शन करने के लिए।
दान ब्रे

25

कलेक्शन क्लास में फेरबदल के लिए एक कुशल विधि है, जिसे कॉपी किया जा सकता है, ताकि उस पर निर्भर न रहें:

/**
 * Usage:
 *    int[] array = {1, 2, 3};
 *    Util.shuffle(array);
 */
public class Util {

    private static Random random;

    /**
     * Code from method java.util.Collections.shuffle();
     */
    public static void shuffle(int[] array) {
        if (random == null) random = new Random();
        int count = array.length;
        for (int i = count; i > 1; i--) {
            swap(array, i - 1, random.nextInt(i));
        }
    }

    private static void swap(int[] array, int i, int j) {
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
}

इसलिए इस पर निर्भर नहीं होना चाहिए ? मैं बहुत कुछ इस पर निर्भर करना चाहूंगा, अगर यह केवल संभव था।
shmosel

@shmosel तब इसका उपयोग करने के लिए स्वतंत्र महसूस करें। सुनिश्चित करें कि आप आवश्यक वर्ग आयात करते हैं और आपने सरणी को सूची में बदल दिया है Arrays.asList। आपको परिणामी सूची को सरणी में बदलना होगा,
किटकैट

आप Arrays.asList()एक आदिम सरणी पर उपयोग नहीं कर सकते । और आपको इसे वापस बदलने की आवश्यकता नहीं होगी क्योंकि यह सिर्फ एक आवरण है।
shmosel

13

को देखो Collectionsवर्ग, विशेष रूप से shuffle(...)


8
आप Android में इस संग्रह वर्ग का उपयोग कैसे करते हैं? इसका उपयोग करने के लिए आपको एक विशेष आयात (CRTL SHIFT O काम नहीं करता है) करने की आवश्यकता है?
ह्यूबर्ट

@ यह पैकेज का हिस्सा होना चाहिए java.util। यह v1.2 के बाद से मानक पुस्तकालय का हिस्सा है।
16

3
अपने उत्तर को अधिक आत्म निहित बनाने के लिए, इसमें उदाहरण कोड होना चाहिए। आईई:import java.util.Collections; shuffle(solutionArray);
स्टेवोइसाक

10

यहाँ Collections.shuffleदृष्टिकोण का उपयोग कर एक पूर्ण समाधान है :

public static void shuffleArray(int[] array) {
  List<Integer> list = new ArrayList<>();
  for (int i : array) {
    list.add(i);
  }

  Collections.shuffle(list);

  for (int i = 0; i < list.size(); i++) {
    array[i] = list.get(i);
  }    
}

ध्यान दें कि यह जावा के अक्षमता को सुचारू रूप से के बीच अनुवाद करने की वजह से ग्रस्त है int[]और Integer[](और इस प्रकार int[]और List<Integer>)।


10

आपके पास यहां कुछ विकल्प हैं। जब यह फेरबदल की बात आती है तो एक सूची सरणी से कुछ अलग होती है।

जैसा कि आप नीचे देख सकते हैं, एक सरणी सूची की तुलना में तेज़ है, और एक आदिम सरणी किसी ऑब्जेक्ट सरणी से तेज़ है।

नमूना अवधि

List<Integer> Shuffle: 43133ns
    Integer[] Shuffle: 31884ns
        int[] Shuffle: 25377ns

नीचे, एक फेरबदल के तीन अलग-अलग कार्यान्वयन हैं। यदि आप एक संग्रह के साथ काम कर रहे हैं तो आपको केवल संग्रह.शफल का उपयोग करना चाहिए। इसे छाँटने के लिए अपने सरणी को एक संग्रह में लपेटने की आवश्यकता नहीं है। नीचे दिए गए तरीके लागू करने के लिए बहुत सरल हैं।

शफलूलेट क्लास

import java.lang.reflect.Array;
import java.util.*;

public class ShuffleUtil<T> {
    private static final int[] EMPTY_INT_ARRAY = new int[0];
    private static final int SHUFFLE_THRESHOLD = 5;

    private static Random rand;

मुख्य विधि

    public static void main(String[] args) {
        List<Integer> list = null;
        Integer[] arr = null;
        int[] iarr = null;

        long start = 0;
        int cycles = 1000;
        int n = 1000;

        // Shuffle List<Integer>
        start = System.nanoTime();
        list = range(n);
        for (int i = 0; i < cycles; i++) {
            ShuffleUtil.shuffle(list);
        }
        System.out.printf("%22s: %dns%n", "List<Integer> Shuffle", (System.nanoTime() - start) / cycles);

        // Shuffle Integer[]
        start = System.nanoTime();
        arr = toArray(list);
        for (int i = 0; i < cycles; i++) {
            ShuffleUtil.shuffle(arr);
        }
        System.out.printf("%22s: %dns%n", "Integer[] Shuffle", (System.nanoTime() - start) / cycles);

        // Shuffle int[]
        start = System.nanoTime();
        iarr = toPrimitive(arr);
        for (int i = 0; i < cycles; i++) {
            ShuffleUtil.shuffle(iarr);
        }
        System.out.printf("%22s: %dns%n", "int[] Shuffle", (System.nanoTime() - start) / cycles);
    }

एक सामान्य सूची में फेरबदल

    // ================================================================
    // Shuffle List<T> (java.lang.Collections)
    // ================================================================
    @SuppressWarnings("unchecked")
    public static <T> void shuffle(List<T> list) {
        if (rand == null) {
            rand = new Random();
        }
        int size = list.size();
        if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
            for (int i = size; i > 1; i--) {
                swap(list, i - 1, rand.nextInt(i));
            }
        } else {
            Object arr[] = list.toArray();

            for (int i = size; i > 1; i--) {
                swap(arr, i - 1, rand.nextInt(i));
            }

            ListIterator<T> it = list.listIterator();
            int i = 0;

            while (it.hasNext()) {
                it.next();
                it.set((T) arr[i++]);
            }
        }
    }

    public static <T> void swap(List<T> list, int i, int j) {
        final List<T> l = list;
        l.set(i, l.set(j, l.get(i)));
    }

    public static <T> List<T> shuffled(List<T> list) {
        List<T> copy = copyList(list);
        shuffle(copy);
        return copy;
    }

जेनेरिक एरे को फेरना

    // ================================================================
    // Shuffle T[]
    // ================================================================
    public static <T> void shuffle(T[] arr) {
        if (rand == null) {
            rand = new Random();
        }

        for (int i = arr.length - 1; i > 0; i--) {
            swap(arr, i, rand.nextInt(i + 1));
        }
    }

    public static <T> void swap(T[] arr, int i, int j) {
        T tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

    public static <T> T[] shuffled(T[] arr) {
        T[] copy = Arrays.copyOf(arr, arr.length);
        shuffle(copy);
        return copy;
    }

एक आदिम ऐरे को फेरना

    // ================================================================
    // Shuffle int[]
    // ================================================================
    public static <T> void shuffle(int[] arr) {
        if (rand == null) {
            rand = new Random();
        }

        for (int i = arr.length - 1; i > 0; i--) {
            swap(arr, i, rand.nextInt(i + 1));
        }
    }

    public static <T> void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

    public static int[] shuffled(int[] arr) {
        int[] copy = Arrays.copyOf(arr, arr.length);
        shuffle(copy);
        return copy;
    }

उपयोगिता के तरीके

सूचियों और इसके विपरीत में सरणियों को कॉपी और परिवर्तित करने की सरल उपयोगिता विधियां।

    // ================================================================
    // Utility methods
    // ================================================================
    protected static <T> List<T> copyList(List<T> list) {
        List<T> copy = new ArrayList<T>(list.size());
        for (T item : list) {
            copy.add(item);
        }
        return copy;
    }

    protected static int[] toPrimitive(Integer[] array) {
        if (array == null) {
            return null;
        } else if (array.length == 0) {
            return EMPTY_INT_ARRAY;
        }
        final int[] result = new int[array.length];
        for (int i = 0; i < array.length; i++) {
            result[i] = array[i].intValue();
        }
        return result;
    }

    protected static Integer[] toArray(List<Integer> list) {
        return toArray(list, Integer.class);
    }

    protected static <T> T[] toArray(List<T> list, Class<T> clazz) {
        @SuppressWarnings("unchecked")
        final T[] arr = list.toArray((T[]) Array.newInstance(clazz, list.size()));
        return arr;
    }

रेंज क्लास

पायथन के rangeकार्य के समान मूल्यों की एक श्रृंखला उत्पन्न करता है।

    // ================================================================
    // Range class for generating a range of values.
    // ================================================================
    protected static List<Integer> range(int n) {
        return toList(new Range(n), new ArrayList<Integer>());
    }

    protected static <T> List<T> toList(Iterable<T> iterable) {
        return toList(iterable, new ArrayList<T>());
    }

    protected static <T> List<T> toList(Iterable<T> iterable, List<T> destination) {
        addAll(destination, iterable.iterator());

        return destination;
    }

    protected static <T> void addAll(Collection<T> collection, Iterator<T> iterator) {
        while (iterator.hasNext()) {
            collection.add(iterator.next());
        }
    }

    private static class Range implements Iterable<Integer> {
        private int start;
        private int stop;
        private int step;

        private Range(int n) {
            this(0, n, 1);
        }

        private Range(int start, int stop) {
            this(start, stop, 1);
        }

        private Range(int start, int stop, int step) {
            this.start = start;
            this.stop = stop;
            this.step = step;
        }

        @Override
        public Iterator<Integer> iterator() {
            final int min = start;
            final int max = stop / step;

            return new Iterator<Integer>() {
                private int current = min;

                @Override
                public boolean hasNext() {
                    return current < max;
                }

                @Override
                public Integer next() {
                    if (hasNext()) {
                        return current++ * step;
                    } else {
                        throw new NoSuchElementException("Range reached the end");
                    }
                }

                @Override
                public void remove() {
                    throw new UnsupportedOperationException("Can't remove values from a Range");
                }
            };
        }
    }
}

1
आप समान चीजों को टाइम नहीं कर रहे हैं और आप हर एक को केवल एक बार टाइम कर रहे हैं (फिर उनका ऑर्डर मायने रखता है और आप रनटाइम ऑप्टिमाइज़ेशन भूल जाते हैं)। आपको कॉल करना चाहिए range, toArrayऔर toPrimitiveकिसी भी समय से पहले, और लूप कुछ भी समाप्त करने में सक्षम होने के लिए (छद्म-कोड: कई बार करें {सूची, गिरफ्तारी और आईआरई; समय फेरबदल सूची; समय फेरबदल गिरफ्तार; समय फेरबदल आईआरई))। मेरे परिणाम: 1 list: 36017ns, arr: 28262ns, iarr: 23334ns:। 100 वीं: list: 18445ns, arr: 19995ns, iarr: 18657ns। यह सिर्फ int [] पूर्व-अनुकूलित (कोड द्वारा) दिखाता है, लेकिन वे रनटाइम अनुकूलन के साथ लगभग बराबर हैं।
13

9

उपयोग ArrayList<Integer>करने से आप बिना तर्क के अधिक आवेदन करने और कम समय का उपभोग करने के लिए फेरबदल की समस्या को हल करने में मदद कर सकते हैं। यहाँ मेरा सुझाव है:

ArrayList<Integer> x = new ArrayList<Integer>();
for(int i=1; i<=add.length(); i++)
{
    x.add(i);
}
Collections.shuffle(x);

शायद बाद वाला नहीं - कम समय लेने वाला । वास्तव में यह निश्चित रूप से ऊपर के आदिम कार्यान्वयन की तुलना में धीमा है।
बोरिस द स्पाइडर

1
किसी को कोड कॉपी करने के लिए, "साइकिल के लिए" i = 1 देखें, शायद आपको i = 0 की आवश्यकता है
बोरिस कार्लॉफ़


5

अब आप java 8 का उपयोग कर सकते हैं:

Collections.addAll(list, arr);
Collections.shuffle(list);
cardsList.toArray(arr);

2
इस कोड में कुछ भी जावा-विशिष्ट नहीं है। यह Java2 के बाद से काम करता है। ठीक है, यह काम करेगा, एक बार जब आप पहली बार उपयोग करने listऔर अचानक संदर्भित करने के बीच असंगतता को ठीक करते हैं cardsList। लेकिन चूंकि आपको अस्थायी बनाने की आवश्यकता है list, जिसे आपने छोड़ दिया है, Collections.shuffle(Arrays.asList(arr));यहां कई बार दिखाए गए दृष्टिकोण पर कोई लाभ नहीं है। जो Java2 के बाद से भी काम करता है।
होल्गर

3

यहाँ सरणियों के लिए एक सामान्य संस्करण है:

import java.util.Random;

public class Shuffle<T> {

    private final Random rnd;

    public Shuffle() {
        rnd = new Random();
    }

    /**
     * Fisher–Yates shuffle.
     */
    public void shuffle(T[] ar) {
        for (int i = ar.length - 1; i > 0; i--) {
            int index = rnd.nextInt(i + 1);
            T a = ar[index];
            ar[index] = ar[i];
            ar[i] = a;
        }
    }
}

यह देखते हुए कि ArrayList मूल रूप से एक सरणी है, स्पष्ट सरणी के बजाय ArrayList के साथ काम करना और Collections.shuffle () का उपयोग करना उचित हो सकता है। प्रदर्शन परीक्षण हालांकि, उपरोक्त और संग्रह के बीच कोई महत्वपूर्ण अंतर नहीं दिखाते हैं। ():

Shuffe<Integer>.shuffle(...) performance: 576084 shuffles per second
Collections.shuffle(ArrayList<Integer>) performance: 629400 shuffles per second
MathArrays.shuffle(int[]) performance: 53062 shuffles per second

अपाचे कॉमन्स कार्यान्वयन MathArrays.shuffle int [] तक सीमित है और यादृच्छिक संख्या जनरेटर का उपयोग किए जाने के कारण प्रदर्शन जुर्माना होने की संभावना है।


1
ऐसा लगता है कि आप पास कर सकते हैं new JDKRandomGenerator()करने के लिए MathArrays.shuffle। मुझे आश्चर्य है कि प्रदर्शन को कैसे प्रभावित करता है?
ब्रैंडन

वास्तव में ... ऐसा लगता है कि MathArrays#shuffleइसके कोर लूप में आवंटन है int targetIdx = new UniformIntegerDistribution(rng, start, i).sample();:। विचित्र।
ब्रैंडन

3
Random rnd = new Random();
for (int i = ar.length - 1; i > 0; i--)
{
  int index = rnd.nextInt(i + 1);
  // Simple swap
  int a = ar[index];
  ar[index] = ar[i];
  ar[i] = a;
}

वैसे, मैंने देखा है कि यह कोड ar.length - 1कई तत्वों को लौटाता है , इसलिए यदि आपके सरणी में 5 तत्व हैं, तो नए फेरबदल वाले सरणी में 4 तत्व होंगे। ऐसा इसलिए होता है क्योंकि लूप कहता है i>0। यदि आप बदलते हैं i>=0, तो आपको सभी तत्व मिल जाएंगे।


बस एक हेड अप, आप इसे अपने प्रश्न के टिप्पणी अनुभाग में स्थानांतरित करना चाह सकते हैं, क्योंकि यह संभवतः झंडी हो जाएगी यदि इसे अपने स्वयं के उत्तर के रूप में छोड़ दिया जाए।
जेसन डी

1
यह प्रश्न का उत्तर देता प्रतीत होता है, इसलिए मैं अनिश्चित हूं कि आप @JasonD के बारे में क्या बात कर रहे हैं
Sumurai8

1
कोड सही है, टिप्पणी गलत है। यदि आप बदलते i>0हैं i>=0, तो आप 0स्वयं के साथ तत्व स्वैप करके समय बर्बाद करते हैं।
jcsahnwaldt मोनिका

3

यहाँ Apache Commons Math 3.x (उदाहरण के लिए [केवल सरणियाँ) का उपयोग करके एक समाधान दिया गया है:

MathArrays.shuffle(array);

http://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/util/MathArrays.html#shuffle (int [])

वैकल्पिक रूप से, अपाचे कॉमन्स लैंग 3.6 ने ArrayUtilsवर्ग के लिए नए फेरबदल के तरीके (वस्तुओं और किसी भी आदिम प्रकार के लिए) पेश किए।

ArrayUtils.shuffle(array);

http://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/ArrayUtils.html#shuffle-int:A-


3

मैंने कुछ उत्तरों में कुछ मिस जानकारी देखी, इसलिए मैंने एक नया जोड़ने का फैसला किया।

Java संग्रह Arrays.asList, T का var-arg लेता है (T ...)। यदि आप एक आदिम सरणी (int array) पास करते हैं, तो asList मेथड List<int[]>एक एलीमेंट लिस्ट (जो एक एलीमेन्टिव एरे है) एक एलीमेंट जेनरेट करेगा । यदि आप इस एक तत्व सूची में फेरबदल करते हैं, तो यह किसी भी चीज को बदल नहीं सकता है।

तो, पहले आपको आपको आदिम सरणी को रैपर ऑब्जेक्ट सरणी में बदलना होगा। इसके लिए आप ArrayUtils.toObjectapache.commons.lang से विधि का उपयोग कर सकते हैं । तब उत्पन्न सरणी को एक सूची और अंतिम फेरबदल से गुजारें।

  int[] intArr = {1,2,3};
  List<Integer> integerList = Arrays.asList(ArrayUtils.toObject(array));
  Collections.shuffle(integerList);
  //now! elements in integerList are shuffled!

3

यहाँ एक सूची में फेरबदल करने का एक और तरीका है

public List<Integer> shuffleArray(List<Integer> a) {
List<Integer> b = new ArrayList<Integer>();
    while (a.size() != 0) {
        int arrayIndex = (int) (Math.random() * (a.size()));
        b.add(a.get(arrayIndex));
        a.remove(a.get(arrayIndex));
    }
    return b;
}

मूल सूची से एक यादृच्छिक संख्या चुनें और इसे किसी अन्य सूची में सहेजें। फिर मूल सूची से संख्या हटा दें। मूल सूची का आकार तब तक घटता रहेगा जब तक कि सभी तत्व नई सूची में नहीं चले जाते।


2

ग्रूवी के लिए एक सरल समाधान:

solutionArray.sort{ new Random().nextInt() }

यह सरणी सूची के सभी तत्वों को बेतरतीब ढंग से क्रमबद्ध करेगा जो सभी तत्वों के फेरबदल के वांछित परिणाम को संग्रहीत करता है।



1

मैं इस बहुत ही लोकप्रिय प्रश्न का वजन कर रहा हूं क्योंकि किसी ने भी फेरबदल-कॉपी संस्करण नहीं लिखा है। शैली को भारी मात्रा में उधार लिया गया है Arrays.java, क्योंकि इन दिनों जावा प्रौद्योगिकी को कौन सुधारे नहीं है ? सामान्य और intकार्यान्वयन शामिल हैं।

   /**
    * Shuffles elements from {@code original} into a newly created array.
    *
    * @param original the original array
    * @return the new, shuffled array
    * @throws NullPointerException if {@code original == null}
    */
   @SuppressWarnings("unchecked")
   public static <T> T[] shuffledCopy(T[] original) {
      int originalLength = original.length; // For exception priority compatibility.
      Random random = new Random();
      T[] result = (T[]) Array.newInstance(original.getClass().getComponentType(), originalLength);

      for (int i = 0; i < originalLength; i++) {
         int j = random.nextInt(i+1);
         result[i] = result[j];
         result[j] = original[i];
      }

      return result;
   }


   /**
    * Shuffles elements from {@code original} into a newly created array.
    *
    * @param original the original array
    * @return the new, shuffled array
    * @throws NullPointerException if {@code original == null}
    */
   public static int[] shuffledCopy(int[] original) {
      int originalLength = original.length;
      Random random = new Random();
      int[] result = new int[originalLength];

      for (int i = 0; i < originalLength; i++) {
         int j = random.nextInt(i+1);
         result[i] = result[j];
         result[j] = original[i];
      }

      return result;
   }

1

यह नथ शफल एल्गोरिथम है।

public class Knuth { 

    // this class should not be instantiated
    private Knuth() { }

    /**
     * Rearranges an array of objects in uniformly random order
     * (under the assumption that <tt>Math.random()</tt> generates independent
     * and uniformly distributed numbers between 0 and 1).
     * @param a the array to be shuffled
     */
    public static void shuffle(Object[] a) {
        int n = a.length;
        for (int i = 0; i < n; i++) {
            // choose index uniformly in [i, n-1]
            int r = i + (int) (Math.random() * (n - i));
            Object swap = a[r];
            a[r] = a[i];
            a[i] = swap;
        }
    }

    /**
     * Reads in a sequence of strings from standard input, shuffles
     * them, and prints out the results.
     */
    public static void main(String[] args) {

        // read in the data
        String[] a = StdIn.readAllStrings();

        // shuffle the array
        Knuth.shuffle(a);

        // print results.
        for (int i = 0; i < a.length; i++)
            StdOut.println(a[i]);
    }
}

1

एक और तरीका भी है, अभी पोस्ट नहीं है

//that way, send many object types diferentes
public anotherWayToReciveParameter(Object... objects)
{
    //ready with array
    final int length =objects.length;
    System.out.println(length);
    //for ready same list
    Arrays.asList(objects);
}

इस तरह से और अधिक आसान, संदर्भ के आधार पर


1

एक ऐरे में इस यादृच्छिक फेरबदल के लिए सबसे सरल समाधान।

String location[] = {"delhi","banglore","mathura","lucknow","chandigarh","mumbai"};
int index;
String temp;
Random random = new Random();
for(int i=1;i<location.length;i++)
{
    index = random.nextInt(i+1);
    temp = location[index];
    location[index] = location[i];
    location[i] = temp;
    System.out.println("Location Based On Random Values :"+location[i]);
}

1
  1. बॉक्स से int[]करने के लिएInteger[]
  2. Arrays.asListविधि के साथ एक सूची में एक सरणी लपेटें
  3. Collections.shuffleविधि से फेरबदल करें

    int[] solutionArray = { 1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1 };
    
    Integer[] boxed = Arrays.stream(solutionArray).boxed().toArray(Integer[]::new);
    Collections.shuffle(Arrays.asList(boxed));
    
    System.out.println(Arrays.toString(boxed));
    // [1, 5, 5, 4, 2, 6, 1, 3, 3, 4, 2, 6]

1

फेरबदल करने के लिए सबसे सरल कोड:

import java.util.*;
public class ch {
    public static void main(String args[])
    {
        Scanner sc=new Scanner(System.in);
        ArrayList<Integer> l=new ArrayList<Integer>(10);
        for(int i=0;i<10;i++)
            l.add(sc.nextInt());
        Collections.shuffle(l);
        for(int j=0;j<10;j++)
            System.out.println(l.get(j));       
    }
}

1

रैंडम क्लास का उपयोग करना

  public static void randomizeArray(int[] arr) {

      Random rGenerator = new Random(); // Create an instance of the random class 
      for (int i =0; i< arr.length;i++ ) {
          //Swap the positions...

          int rPosition = rGenerator.nextInt(arr.length); // Generates an integer within the range (Any number from 0 - arr.length)
          int temp = arr[i]; // variable temp saves the value of the current array index;
          arr[i] = arr[rPosition];  // array at the current position (i) get the value of the random generated 
          arr[rPosition] = temp; // the array at the position of random generated gets the value of temp

      }

      for(int i = 0; i<arr.length; i++) {
          System.out.print(arr[i]); //Prints out the array
      } 

  }

0
public class ShuffleArray {
public static void shuffleArray(int[] a) {
    int n = a.length;
    Random random = new Random();
    random.nextInt();
    for (int i = 0; i < n; i++) {
        int change = i + random.nextInt(n - i);
        swap(a, i, change);
    }
}

private static void swap(int[] a, int i, int change) {
    int helper = a[i];
    a[i] = a[change];
    a[change] = helper;
}

public static void main(String[] args) {
    int[] a = new int[] { 1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1 };
    shuffleArray(a);
    for (int i : a) {
        System.out.println(i);
    }
}
}

कृपया अपने उत्तर के संबंध में कुछ संबंधित विवरण जोड़ें।
अंकित सुथार

0
import java.util.ArrayList;
import java.util.Random;
public class shuffle {
    public static void main(String[] args) {
        int a[] =  {1,2,3,4,5,6,7,8,9};
         ArrayList b = new ArrayList();
       int i=0,q=0;
       Random rand = new Random();

       while(a.length!=b.size())
       {
           int l = rand.nextInt(a.length);
//this is one option to that but has a flaw on 0
//           if(a[l] !=0)
//           {
//                b.add(a[l]);
//               a[l]=0;
//               
//           }
//           
// this works for every no. 
                if(!(b.contains(a[l])))
                {
                    b.add(a[l]);
                }



       }

//        for (int j = 0; j <b.size(); j++) {
//            System.out.println(b.get(j));
//            
//        }
System.out.println(b);
    }

}

0

स्वैप b का उपयोग किए बिना समान

        Random r = new Random();
    int n = solutionArray.length;
    List<Integer> arr =  Arrays.stream(solutionArray).boxed().collect(Collectors.toList());
    for (int i = 0; i < n-1; i++) {
        solutionArray[i] = arr.remove( r.nextInt(arr.size())); // randomize base on size
    }
    solutionArray[n-1] = arr.get(0);

0

समाधान में से एक क्रमपरिवर्तन का उपयोग करके सभी क्रमपरिवर्तन को पूर्व-गणना करने और ArrayList में संग्रहीत किया जाता है

जावा 8 ने java.util.Random क्लास में एक नया तरीका, ints () पेश किया। Ints () विधि pseudorandom int मानों की एक असीमित धारा देता है। आप न्यूनतम और अधिकतम मान प्रदान करके एक निर्दिष्ट सीमा के बीच यादृच्छिक संख्याओं को सीमित कर सकते हैं।

Random genRandom = new Random();
int num = genRandom.nextInt(arr.length);

यादृच्छिक संख्या उत्पन्न करने की सहायता से, आप लूप के माध्यम से पुनरावृति कर सकते हैं और यादृच्छिक संख्या के साथ वर्तमान सूचकांक के साथ स्वैप कर सकते हैं .. यही कारण है कि आप O (1) अंतरिक्ष जटिलता के साथ एक यादृच्छिक संख्या उत्पन्न कर सकते हैं।


0

यादृच्छिक समाधान के बिना:

   static void randomArrTimest(int[] some){
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < some.length; i++) {
            long indexToSwap = startTime%(i+1);
            long tmp = some[(int) indexToSwap];
            some[(int) indexToSwap] = some[i];
            some[i] = (int) tmp;
        }
        System.out.println(Arrays.toString(some));
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.