Bir dizinin rastgele karıştırılması


232

Aşağıdaki Dizi rastgele karıştırmak gerekir:

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

Bunu yapmak için herhangi bir işlev var mı?


5
Collections.shuffle (Arrays.asList (dizi)) aradığınız SDK yöntemidir;
Louis Hong

2
@Louie Hayır, bu işe yaramıyor. Bu, List<int[]>tek bir giriş oluşturacaktır . Bu kullanımı elde etmenin yolu için cevabımı görün Collections.shuffle().
Duncan Jones

2
Orijinal soruya gerçekten bir cevap değil, ancak commons-math3 kütüphanesinden MathArrays.shuffle işi yapar.
sandris

1
Bu bir yanıtı garanti etmek için yeterince konuyla ilgili değil, ama "Grafik Taşlar" kitabından sözde rasgele sırada bir dizi geçmekten bahseden gerçekten harika bir makale hatırlıyorum. Zihnimde, verileri ilk etapta karıştırmak zorunda kalmaz. C-uygulaması burada bulunabilir github.com/erich666/GraphicsGems/blob/master/gems/Dissolve.c
Lennart Rolland

Ayrıca bu yakından alakalı soruya bakın: stackoverflow.com/questions/2450954/…
Pierz

Yanıtlar:


263

Bir dizi ilkel türü karıştırmak için Koleksiyonlar'ı kullanmak biraz fazladır ...

Örneğin Fisher – Yates shuffle'ı kullanarak işlevi kendiniz uygulamak yeterince basittir :

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
Son derece önemsiz nitpick, ancak println()yerine kullanabilirsiniz println(""). Sanırım niyetinde net :)
Cowan

55
Collections.shuffle (Arrays.asList (dizi)) kullanmak çok daha iyi olur; sonra kendiniz bir karıştırın.
Louis Hong

21
@Louie Collections.shuffle(Arrays.asList(array))çünkü iş, değil Arrays.asList(array)döner Collection<int[]>değil Collection<Integer>düşündüğün kadar.
Adam Stelmaszczyk

15
@exhuma Çünkü sıralayacağınız binlerce veya milyonlarca ilkel değer diziniz varsa, her birini sadece bir sıralama yapmak için bir nesneye sarmak hem bellekte hem de CPU'da biraz maliyetlidir.
PhiLho

14
Bu değil Fisher-Yates karıştırmak. Buna Durstenfeld shuffle denir . Orijinal fisher-yates shuffle çok yavaş olan O (n ^ 2) sürede çalışır.
Pacerier

164

İşte bir kullanarak basit bir yol ArrayList:

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

1
Basitçe yapabilirsinizCollectons.shuffle(Arrays.asList(solutionArray));
FindOutIslamNow

@Timmos Yanılıyorsun. Arrays.asList orijinal dizinin etrafını sarar ve böylece değiştirilirse orijinal dizi değişir. Bu yüzden ekleyemez veya kaldıramazsınız, çünkü diziler sabit boyuttadır.
Nand

@Nand düşündüğümden emin değilim, ancak kaynak koduna baktığımızda, gerçekten de Arrays.asList yöntemi, verilen dizi tarafından desteklenen bir ArrayList oluşturur. Gösterdiğiniz için teşekkürler. Önceki yorumumu sildim (düzenlenemedi).
Timmos

100

İşte çalışan ve verimli bir Fisher – Yates shuffle dizi işlevi:

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];
        }
    }
}

veya

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
Bir Tamsayı Koleksiyonu yaratma yükü yüksek olmayan bir çözüme ihtiyacım olduğu için oy verdim
mwk

2
İkinci uygulamanın kendi endeksiyle değiştirme potansiyeli yok mu? random.nextInt(int bound)münhasırdır, ancak bunu i + 1bir argüman olarak vermek izin verir indexve ipotansiyel olarak aynı olur.
bmcentee148

21
@ bmcentee148 Rastgele bir sırada bir öğenin kendisi ile değiştirilmesine izin verilir. Bunun anlaşılmaması Enigma'yı zayıflattı ve Alan Turing'in onu kırmasına yardımcı oldu. en.wikipedia.org/wiki/…
Ellen Spertus

4
xorHile İşlemci hiçbir takas talimat vardır ve hiç boş kayıtları varken CPU kayıtlarını takas için harika ama içinde bir döngü dizi elemanlarını takas için, herhangi bir fayda görmüyorum. Geçici yerel değişkenler için, bunların döngü dışında bildirilmesi için bir neden yoktur.
Holger

1
tempDeğişkeni döngü dışında bildirmek biraz daha etkilidir . XORHüner hızlı bir kullanmaktan daha olmalıdır tempemin bir kıyaslama testi gerçekleştirmek için olmak değişken ama tek yol.
Dan Bray

25

Koleksiyonlar sınıfının karıştırma için, kopyalanmayacak şekilde etkin bir yöntemi vardır;

/**
 * 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;
    }
}

güvenmemek için ? Sadece mümkün olsaydı, ona güvenmeyi çok isterdim.
shmosel

@shmosel O zaman kullanmaktan çekinmeyin. Gerekli sınıfı aldığınızdan ve diziyi ile listeye dönüştürdüğünüzden emin olun Arrays.asList. Sonuç listesini de bir diziye dönüştürmelisiniz
KitKat

Arrays.asList()İlkel bir dizide kullanamazsınız . Ve geri dönüştürmeniz gerekmeyecek çünkü bu sadece bir sarıcı.
shmosel

13

CollectionsÖzellikle sınıfa bakın shuffle(...).


8
Bu Koleksiyonlar sınıfını Android'de nasıl kullanıyorsunuz? Kullanmak için özel bir ithalat (CRTL SHIFT O çalışmıyor) yapmanız mı gerekiyor?
Hubert

@Hubert paketin bir parçası olmalı java.util. Sürüm 1.2'den beri standart kütüphanenin bir parçasıdır.
MauganRa

3
Cevabınızı daha kendi içinde tutmak için örnek kod içermelidir. IE:import java.util.Collections; shuffle(solutionArray);
Stevoisiak

10

Collections.shuffleYaklaşımı kullanan eksiksiz bir çözüm :

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);
  }    
}

Java'nın int[]ve Integer[](ve dolayısıyla int[]ve List<Integer>) arasında düzgün bir şekilde çeviri yapamaması nedeniyle acı çektiğini unutmayın .


10

Burada birkaç seçeneğiniz var. Karıştırma söz konusu olduğunda liste bir diziden biraz farklıdır.

Aşağıda görebileceğiniz gibi, bir dizi bir listeden daha hızlıdır ve ilkel bir dizi bir nesne dizisinden daha hızlıdır.

Örnek Süreler

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

Aşağıda, bir shuffle'ın üç farklı uygulaması vardır. Collections.shuffle öğesini yalnızca bir koleksiyonla uğraşıyorsanız kullanmalısınız. Dizinizi sadece sıralamak için bir koleksiyona sarmanıza gerek yoktur. Aşağıdaki yöntemlerin uygulanması çok basittir.

ShuffleUtil Sınıfı

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;

Ana Yöntem

    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);
    }

Genel Listenin Karıştırılması

    // ================================================================
    // 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;
    }

Genel Diziyi Karıştırma

    // ================================================================
    // 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;
    }

İlkel Diziyi Karıştırma

    // ================================================================
    // 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;
    }

Fayda Yöntemleri

Dizileri kopyalamak ve listelere dönüştürmek için basit yardımcı yöntemler.

    // ================================================================
    // 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;
    }

Sınıf Aralığı

Python'un rangeişlevine benzer bir dizi değer üretir .

    // ================================================================
    // 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
Aynı şeyleri zamanlamıyorsunuz ve her birini sadece bir kez zamanlıyorsunuz (o zaman siparişleri önemlidir ve çalışma zamanı optimizasyonunu unutursunuz). Sen aramalısınız range, toArrayve toPrimitiveherhangi bir zamanlama ve döngü önce bir şey sonuçlandırmak edebilmek için (sözde kodu: birkaç kez {listesini oluşturmak, arr ve iarr; zaman listesini karıştırma; sefer karıştırma varış; zaman iarr karıştırma} yoktur). Benim sonuçları: 1: list: 36017ns, arr: 28262ns, iarr: 23334ns. 100.: list: 18445ns, arr: 19995ns, iarr: 18657ns. Sadece int [] 'nin önceden kodlanmış olduğunu (koda göre) gösterir, ancak çalışma zamanı optimizasyonu ile neredeyse eşdeğerdir.
syme

9

Kullanmak ArrayList<Integer>, fazla mantık uygulamadan ve daha az zaman harcamadan karıştırma problemini çözmenize yardımcı olabilir. İşte önerim:

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

Muhtemelen ikincisi değil - daha az zaman harcıyor . Aslında bu kesinlikle yukarıdaki ilkel uygulamalardan daha yavaştır.
Örümcek Boris

1
Birisi kodu kopyalar için, "döngüsü için" i = 1 izleyin belki i = 0 gerekir
Boris Karloff


5

Java 8'i şimdi kullanabilirsiniz:

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

2
Bu kodda Java8'e özgü hiçbir şey yoktur. Bu Java2'den beri çalışır. İlk kullanım listile aniden başvurmak arasındaki tutarsızlığı düzelttiğinizde işe yarayacaktır cardsList. Ancak listatladığınız geçici olanı yaratmanız gerektiğinden , Collections.shuffle(Arrays.asList(arr));burada birkaç kez gösterilen yaklaşımdan faydası yoktur . Hangi Java2 beri çalışır.
Holger

3

İşte diziler için bir Generics sürümü:

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'in temel olarak sadece bir dizi olduğu düşünüldüğünde, açık dizi yerine bir ArrayList ile çalışmanız ve Collections.shuffle () kullanılması tavsiye edilebilir. Ancak performans testleri, yukarıdakiler ve Collections.sort () arasında önemli bir fark göstermez:

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

Apache Commons uygulaması MathArrays.shuffle int [] ile sınırlıdır ve performans cezası büyük olasılıkla kullanılan rasgele sayı üretecinden kaynaklanmaktadır.


1
Eğer geçebilir gibi görünüyor new JDKRandomGenerator()için MathArrays.shuffle. Bunun performansı nasıl etkilediğini merak ediyorum.
Brandon

Gibi Aslında ... görünüyor MathArrays#shuffleçekirdek döngüde bir tahsisini vardır: int targetIdx = new UniformIntegerDistribution(rng, start, i).sample();. Tuhaf.
Brandon,

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;
}

Bu arada, bu kodun bir ar.length - 1dizi öğe döndürdüğünü fark ettim, bu yüzden dizinizde 5 öğe varsa, yeni karıştırılmış dizi 4 öğeye sahip olacaktır. Çünkü for döngüsü diyor i>0. Olarak değiştirirseniz i>=0, tüm öğeleri karıştırırsınız.


Sadece bir adım yukarı, bunu sorunuzun yorum bölümüne taşımak isteyebilirsiniz, çünkü kendi cevabı olarak bırakılırsa muhtemelen işaretlenir.
Jason D

1
Bu soruya cevap veriyor gibi görünüyor, bu yüzden ne hakkında konuştuğunuzdan emin değilim @JasonD
Sumurai8

1
Kod doğru, yorum yanlış. Eğer değiştirirseniz i>0için i>=0, size elemanı değiştirerek zaman kaybetmeyin 0kendisiyle.
jcsahnwaldt Reinstate Monica

3

Apache Commons Math 3.x kullanan bir çözüm (yalnızca int [] dizileri için):

MathArrays.shuffle(array);

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

Alternatif olarak, Apache Commons Lang 3.6 ArrayUtilssınıfa yeni shuffle yöntemleri getirmiştir (nesneler ve herhangi bir ilkel tip için).

ArrayUtils.shuffle(array);

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


3

Bazı cevaplarda bazı özledim bilgileri gördüm, bu yüzden yeni bir tane eklemeye karar verdim.

Java koleksiyonları Arrays.asList, T türünün değişkenini alır (T ...). Bir ilkel dizi (int dizi) iletirseniz, asList yöntemi çıkarım yapar veList<int[]> bir tek öğe listesi olan (bir öğe ilkel dizidir) . Bu bir öğe listesini karıştırırsanız, hiçbir şeyi değiştirmez.

Yani, önce ilkel diziyi Wrapper nesne dizisine dönüştürmelisiniz. bunun için ArrayUtils.toObjectapache.commons.lang yöntemini kullanabilirsiniz . daha sonra oluşturulan diziyi bir Listeye aktarın ve son olarak karıştırın.

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

3

İşte bir listeyi karıştırmanın başka bir yolu

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;
}

Orijinal listeden rastgele bir sayı seçin ve başka bir listeye kaydedin.


2

Groovy için basit bir çözüm:

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

Bu, dizi listesinin tüm öğelerini, tüm öğelerin karıştırılmasının istenen sonucunu arşivleyen rastgele sıralar.



1

Bu çok popüler soruya ağırlık veriyorum çünkü kimse karışık kopya versiyonunu yazmamış. Stil ağır ödünç Arrays.java, kimin çünkü değil bu gün Java teknolojisini yağma? Genel ve intuygulamalar dahil.

   /**
    * 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

Bu knuth shuffle algoritması.

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

Başka bir yol daha var, henüz posta göndermiyor

//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);
}

bu şekilde içeriğe bağlı olarak daha kolay


1

Bir Dizideki bu Rastgele Karıştırma için en basit çözüm.

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. Kutu gelen int[]etmekInteger[]
  2. Bir diziyi Arrays.asListyöntemle listeye sarma
  3. İle karıştır Collections.shuffleyöntemi

    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

Karıştırmak için en basit kod:

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

Rasgele Sınıfı Kullanma

  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);
    }
}
}

Lütfen cevabınızla ilgili bazı açıklamalar ekleyin.
ankit suthar

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

takas kullanmadan benzer 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

Çözümlerden biri, permütasyonu tüm permütasyonları önceden hesaplamak ve ArrayList'te saklamak için kullanmaktır.

Java 8, java.util.Random sınıfına ints () adlı yeni bir yöntem getirdi. İnts () yöntemi, pseudorandom int değerleri için sınırsız bir akış döndürür. Minimum ve maksimum değerleri sağlayarak, rastgele sayıları belirli bir aralık arasında sınırlayabilirsiniz.

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

Rastgele sayı üretme yardımı ile döngü boyunca yinelenebilir ve mevcut indeksle rastgele sayı ile değiştirilebilir .. O (1) uzay karmaşıklığı ile rastgele bir sayı üretebilirsiniz.


0

Rastgele çözüm olmadan:

   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));
    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.