Pengacakan acak array

232

Saya perlu secara acak mengocok Array berikut:

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

Apakah ada fungsi untuk melakukan itu?

Hubert
sumber
5
Ini adalah metode SDK yang Anda cari Collections.shuffle (Arrays.asList (array));
Louis Hong
2
@ Louie Tidak, itu tidak berhasil. Itu akan membuat List<int[]>satu entri yang berisi. Lihat jawaban saya untuk cara mencapai menggunakan ini Collections.shuffle().
Duncan Jones
2
Tidak benar-benar jawaban untuk pertanyaan asli, tetapi MathArrays.shuffle dari perpustakaan commons-math3 melakukan pekerjaan.
sandris
1
Ini tidak cukup pada topik untuk menjamin jawaban, tapi saya ingat artikel yang sangat keren dari buku "Graphics Gems" yang berbicara tentang melintasi array dalam urutan acak semu. Dalam pikiran saya bahwa detak harus benar-benar mengocok data di tempat pertama. Implementasi C ditemukan di sini github.com/erich666/GraphicsGems/blob/master/gems/Dissolve.c
Lennart Rolland
Lihat juga pertanyaan yang berkaitan erat ini: stackoverflow.com/questions/2450954/…
Pierz

Jawaban:

263

Menggunakan Collections untuk mengocok satu array tipe primitif sedikit berlebihan ...

Cukup sederhana untuk mengimplementasikan fungsi sendiri, menggunakan misalnya Fisher-Yates shuffle :

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;
    }
  }
}
PhiLho
sumber
26
Nitpick yang sangat sepele, tetapi Anda bisa menggunakannya println()saja println(""). Lebih jelas maksudnya :)
Cowan
55
Akan jauh lebih baik menggunakan Collections.shuffle (Arrays.asList (array)); lalu buat shuffle dirimu.
Louis Hong
21
@Louie Collections.shuffle(Arrays.asList(array))tidak berfungsi, karena Arrays.asList(array)kembali Collection<int[]>tidak Collection<Integer>seperti yang Anda pikirkan.
Adam Stelmaszczyk
15
@exhuma Karena jika Anda memiliki array ribuan atau jutaan nilai primitif untuk disortir, membungkus masing-masing dalam suatu objek hanya untuk melakukan semacam itu agak mahal, baik dalam memori dan CPU.
PhiLho
14
Ini bukan shuffle Fisher-Yates. Ini disebut Durstenfeld shuffle . Shuffle fisher-yates asli berjalan dalam waktu O (n ^ 2) yang sangat lambat.
Pacerier
164

Berikut ini cara sederhana menggunakan ArrayList:

List<Integer> solution = new ArrayList<>();
for (int i = 1; i <= 6; i++) {
    solution.add(i);
}
Collections.shuffle(solution);
metodein
sumber
1
Anda dapat dengan mudahCollectons.shuffle(Arrays.asList(solutionArray));
FindOutIslamNow
@Timmos Anda salah. Arrays.asList membungkus array asli dan karenanya memodifikasinya memodifikasi array asli. Itu sebabnya Anda tidak dapat menambah atau menghapus, karena ukuran array adalah tetap.
Nand
@Nand tidak yakin apa yang saya pikirkan, tetapi melihat kode sumber, memang metode Arrays.asList menciptakan ArrayList yang didukung oleh array yang diberikan. Terima kasih telah menunjukkannya. Menghapus komentar saya sebelumnya (tidak dapat mengeditnya).
Timmos
100

Berikut adalah fungsi array shuffle Fisher – Yates yang berfungsi dan efisien:

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

atau

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;
    }
}
Dan Bray
sumber
1
Terpilih karena saya membutuhkan solusi yang tidak memiliki overhead tinggi untuk menciptakan Collection of Integer
mwk
2
Bukankah implementasi kedua memiliki potensi untuk bertukar dengan indeksnya sendiri? random.nextInt(int bound)bersifat eksklusif tetapi memberikannya i + 1sebagai argumen akan memungkinkan indexdan iberpotensi sama.
bmcentee148
21
@ bmcentee148 Menukar elemen dengan dirinya sendiri diizinkan dalam urutan acak. Tidak memahami ini melemahkan Enigma dan membantu memungkinkan Alan Turing untuk memecahkannya. en.wikipedia.org/wiki/…
Ellen Spertus
4
The xortrick sangat bagus untuk bertukar register CPU ketika CPU tidak memiliki instruksi swap dan tidak ada register gratis, tapi untuk bertukar elemen array dalam satu lingkaran, saya tidak melihat manfaat apapun. Untuk variabel lokal sementara, tidak ada alasan untuk mendeklarasikannya di luar loop.
Holger
1
Ini sedikit lebih efisien untuk mendeklarasikan tempvariabel di luar loop. The XORTrik harus lebih cepat daripada menggunakan tempvariabel tetapi satu-satunya cara untuk memastikan itu untuk melakukan tes benchmark.
Dan Bray
25

Kelas koleksi memiliki metode yang efisien untuk pengocokan, yang dapat disalin, agar tidak bergantung padanya:

/**
 * 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;
    }
}
Kit Kat
sumber
agar tidak bergantung padanya ? Saya lebih suka bergantung padanya, jika itu hanya mungkin.
shmosel
@shmosel Maka jangan ragu untuk menggunakannya. Pastikan Anda mengimpor kelas yang diperlukan dan Anda telah mengubah array ke daftar Arrays.asList. Anda harus mengonversi daftar yang dihasilkan menjadi array juga
KitKat
Anda tidak dapat menggunakan Arrays.asList()pada array primitif. Dan Anda tidak perlu mengubahnya kembali karena itu hanya pembungkus.
shmosel
13

Lihatlah Collectionskelasnya, secara khusus shuffle(...).

Dave
sumber
8
Bagaimana Anda menggunakan kelas Koleksi ini di Android? Anda perlu melakukan impor khusus (CRTL SHIFT O tidak berfungsi) untuk menggunakannya?
Hubert
@ Hubert itu harus menjadi bagian dari paket java.util. Itu bagian dari perpustakaan standar sejak v1.2.
MauganRa
3
Agar jawaban Anda lebih lengkap, jawabannya harus berisi kode contoh. IE:import java.util.Collections; shuffle(solutionArray);
Stevoisiak
10

Berikut ini adalah solusi lengkap menggunakan Collections.shufflependekatan:

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

Perhatikan bahwa ia menderita karena ketidakmampuan Java untuk menerjemahkan antara int[]dan Integer[](dan dengan demikian int[]dan List<Integer>) dengan lancar .

Duncan Jones
sumber
10

Anda memiliki beberapa opsi di sini. Daftar sedikit berbeda dari array ketika datang untuk mengocok.

Seperti yang Anda lihat di bawah, array lebih cepat dari daftar, dan array primitif lebih cepat dari array objek.

Durasi Sampel

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

Di bawah, ada tiga implementasi shuffle yang berbeda. Anda hanya harus menggunakan Collections.shuffle jika Anda berurusan dengan koleksi. Tidak perlu membungkus array Anda ke dalam koleksi hanya untuk mengurutkannya. Metode di bawah ini sangat sederhana untuk diterapkan.

Kelas ShuffleUtil

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;

Metode Utama

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

Mengocok Daftar Generik

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

Mengocok Larik Generik

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

Mengocok Array Primitif

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

Metode Utilitas

Metode utilitas sederhana untuk menyalin dan mengonversi array ke daftar dan sebaliknya.

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

Kelas Rentang

Menghasilkan rentang nilai, mirip dengan rangefungsi Python .

    // ================================================================
    // 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");
                }
            };
        }
    }
}
Tuan Polywhirl
sumber
1
Anda tidak menghitung waktu hal-hal yang sama dan Anda menghitung waktu masing-masing hanya satu kali (kemudian pesanannya diperhitungkan & Anda lupa optimasi runtime). Anda harus memanggil range, toArraydan toPrimitivesebelum waktu apa pun, dan mengulang untuk dapat menyimpulkan apa pun (pseudo-code: lakukan beberapa kali {menghasilkan daftar, arr dan iarr; daftar pengocokan waktu; pengocokan pengocokan waktu; pengocokan waktu pengocok}). Hasil saya: 1: list: 36017ns, arr: 28262ns, iarr: 23334ns. 100: list: 18445ns, arr: 19995ns, iarr: 18657ns. Itu hanya menunjukkan int [] adalah pra-dioptimalkan (dengan kode) tetapi mereka hampir setara dengan optimasi runtime.
syme
9

Menggunakan ArrayList<Integer>dapat membantu Anda memecahkan masalah pengocokan tanpa menerapkan banyak logika dan menghabiskan lebih sedikit waktu. Inilah yang saya sarankan:

ArrayList<Integer> x = new ArrayList<Integer>();
for(int i=1; i<=add.length(); i++)
{
    x.add(i);
}
Collections.shuffle(x);
SalmaanKhan
sumber
Mungkin bukan yang terakhir - memakan waktu lebih sedikit . Sebenarnya ini tentunya lebih lambat daripada implementasi primitif di atas.
Boris the Spider
1
Untuk seseorang menyalin kode, perhatikan "untuk siklus" i = 1 mungkin Anda perlu i = 0
Boris Karloff
5

Anda dapat menggunakan java 8 sekarang:

Collections.addAll(list, arr);
Collections.shuffle(list);
cardsList.toArray(arr);
Иван Николайчук
sumber
2
Tidak ada yang spesifik Java8 dalam kode ini. Ini berfungsi sejak Java2. Yah, itu akan berhasil, setelah Anda memperbaiki ketidakkonsistenan antara penggunaan pertama listdan tiba-tiba merujuk cardsList. Tetapi karena Anda perlu membuat sementara list, yang telah Anda hilangkan, tidak ada manfaat atas Collections.shuffle(Arrays.asList(arr));pendekatan yang ditunjukkan beberapa kali di sini. Yang juga berfungsi sejak Java2.
Holger
3

Ini adalah versi Generics untuk array:

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

Menimbang bahwa ArrayList pada dasarnya hanya sebuah array, mungkin disarankan untuk bekerja dengan ArrayList daripada array eksplisit dan menggunakan Collections.shuffle (). Namun tes kinerja, tidak menunjukkan perbedaan yang signifikan antara yang di atas dan Collections.sort ():

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

Implementasi Apache Commons MathArrays.shuffle terbatas pada int [] dan penalti kinerja kemungkinan karena generator nomor acak yang digunakan.

pengguna1050755
sumber
1
Sepertinya Anda dapat melewati new JDKRandomGenerator()ke MathArrays.shuffle. Saya bertanya-tanya bagaimana hal itu memengaruhi kinerja?
Brandon
Sebenarnya ... sepertinya MathArrays#shufflememiliki alokasi dalam lingkaran inti: int targetIdx = new UniformIntegerDistribution(rng, start, i).sample();. Aneh.
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;
}

Ngomong-ngomong, saya perhatikan bahwa kode ini mengembalikan ar.length - 1sejumlah elemen, jadi jika array Anda memiliki 5 elemen, array yang diacak akan memiliki 4 elemen. Ini terjadi karena for for loop mengatakan i>0. Jika Anda mengubah ke i>=0, Anda mendapatkan semua elemen dikocok.

Cristiane Dos Santos Costa
sumber
Hanya kepala saja, Anda mungkin ingin memindahkan ini ke bagian komentar dari pertanyaan Anda, karena mungkin akan ditandai jika dibiarkan sebagai jawaban sendiri.
Jason D
1
Ini sepertinya menjawab pertanyaan, jadi saya tidak yakin apa yang kamu bicarakan tentang @JasonD
Sumurai8
1
Kode sudah benar, komentar salah. Jika Anda berubah i>0menjadi i>=0, Anda membuang waktu dengan menukar elemen 0dengan dirinya sendiri.
jcsahnwaldt Reinstate Monica
3

Berikut adalah solusi menggunakan Apache Commons Math 3.x (hanya untuk array int []):

MathArrays.shuffle(array);

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

Atau, Apache Commons Lang 3.6 memperkenalkan metode shuffle baru ke ArrayUtilskelas (untuk objek dan tipe primitif apa pun).

ArrayUtils.shuffle(array);

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

Emmanuel Bourg
sumber
3

Saya melihat beberapa informasi yang hilang dalam beberapa jawaban jadi saya memutuskan untuk menambahkan yang baru.

Java koleksi Arrays.asList mengambil var-arg tipe T (T ...). Jika Anda melewatkan array primitif (array int), metode asList akan menyimpulkan dan menghasilkan aList<int[]> , yang merupakan daftar satu elemen (elemen satu adalah array primitif). jika Anda mengacak daftar elemen yang satu ini, itu tidak akan mengubah apa pun.

Jadi, pertama-tama Anda harus mengubah Anda array primitif ke array objek Wrapper. untuk ini, Anda dapat menggunakan ArrayUtils.toObjectmetode dari apache.commons.lang. kemudian meneruskan array yang dihasilkan ke Daftar dan akhirnya mengocoknya.

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

Berikut cara lain untuk mengacak daftar

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

Pilih nomor acak dari daftar asli dan simpan di daftar lain. Kemudian hapus nomor dari daftar asli. Ukuran daftar asli akan terus berkurang satu hingga semua elemen dipindahkan ke daftar baru.

PS5
sumber
2

Solusi sederhana untuk Groovy:

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

Ini akan mengurutkan semua elemen daftar array secara acak yang mengarsipkan hasil yang diinginkan dari pengocokan semua elemen.

Hans Kristian
sumber
2

Menggunakan Jambu Ints.asList()itu sesederhana:

Collections.shuffle(Ints.asList(array));
BeeOnRope
sumber
1

Saya mempertimbangkan pertanyaan yang sangat populer ini karena tidak ada yang menulis versi shuffle-copy. Gaya sangat dipinjam dari Arrays.java, karena siapa yang tidak menjarah teknologi Java hari ini? intTermasuk generik dan implementasinya.

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

Ini adalah algoritma knuth shuffle.

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]);
    }
}
BufBills
sumber
1

Ada cara lain juga, belum posting

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

cara itu lebih mudah, tergantung dari konteksnya

Marcelo Ferreira
sumber
1

Solusi paling sederhana untuk Acak Acak ini dalam Array.

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]);
}
Archit Goel
sumber
1
  1. Kotak dari int[]hinggaInteger[]
  2. Bungkus array ke dalam daftar denganArrays.asList metode
  3. Acak dengan Collections.shufflemetode

    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]
YujiSoftware
sumber
1

Kode paling sederhana untuk diacak:

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));       
    }
}
suraj
sumber
1

Menggunakan Kelas Acak

  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
      } 

  }
Fiel Muhongo
sumber
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);
    }
}
}
nikhil gupta
sumber
Harap tambahkan beberapa deskripsi terkait tentang jawaban Anda.
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);
    }

}
aurobind singh
sumber
0

serupa tanpa menggunakan swap 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);
digitebs
sumber
0

Salah satu solusinya adalah menggunakan permutasi untuk pra-menghitung semua permutasi dan disimpan di ArrayList

Java 8 memperkenalkan metode baru, ints (), di kelas java.util.Random. Metode ints () mengembalikan aliran nilai int pseudorandom tak terbatas. Anda dapat membatasi angka acak antara rentang yang ditentukan dengan memberikan nilai minimum dan maksimum.

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

Dengan bantuan menghasilkan nomor acak, Anda dapat mengulangi melalui loop dan bertukar dengan indeks saat ini dengan nomor acak .. Itulah cara Anda dapat menghasilkan angka acak dengan O (1) kompleksitas ruang.


sumber
0

Tanpa solusi acak:

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