Riproduzione casuale di un array


232

Devo mescolare casualmente la seguente matrice:

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

C'è qualche funzione per farlo?


5
Questo è il metodo SDK che stai cercando Collections.shuffle (Arrays.asList (array));
Louis Hong,

2
@Louie No, non funziona. Ciò creerebbe una List<int[]>voce contenente una. Vedi la mia risposta per il modo di raggiungere questo usando Collections.shuffle().
Duncan Jones,

2
Non è proprio una risposta alla domanda originale, ma MathArrays.shuffle della libreria commons-math3 fa il suo lavoro.
sandris,

1
Questo non è abbastanza in argomento per giustificare una risposta, ma ricordo un articolo davvero interessante del libro "Graphics Gems" che parlava di attraversare un array in ordine pseudo casuale. Nella mia mente, è meglio innanzitutto mescolare i dati in modo casuale. L'implementazione in C è disponibile qui github.com/erich666/GraphicsGems/blob/master/gems/Dissolve.c
Lennart Rolland

Vedi anche questa domanda strettamente correlata: stackoverflow.com/questions/2450954/…
Pierz,

Risposte:


263

L'uso delle raccolte per mescolare una serie di tipi primitivi è un po 'eccessivo ...

È abbastanza semplice implementare la funzione da soli, usando ad esempio il riordino Fisher – Yates :

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
Nitpick estremamente banale, ma puoi semplicemente usare println()invece di println(""). Più chiaro nelle intenzioni penso :)
Cowan,

55
Sarebbe molto meglio usare Collections.shuffle (Arrays.asList (array)); poi fai un riordino di te stesso.
Louis Hong,

21
@Louie Collections.shuffle(Arrays.asList(array))non funziona, perché non Arrays.asList(array)ritorna come pensavi. Collection<int[]>Collection<Integer>
Adam Stelmaszczyk il

15
@exhuma Perché se hai un array di migliaia o milioni di valori primitivi da ordinare, avvolgere ognuno in un oggetto solo per fare un ordinamento è un po 'costoso, sia nella memoria che nella CPU.
PhiLho,

14
Questo non è lo shuffle Fisher-Yates. Questo si chiama Durstenfeld shuffle . L'originale shuffle di fisher-yates corre nel tempo O (n ^ 2) che è estremamente lento.
Pacerier,

164

Ecco un modo semplice usando un ArrayList:

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

1
Puoi semplicementeCollectons.shuffle(Arrays.asList(solutionArray));
FindOutIslamNow

@Timmos Ti sbagli. Arrays.asList avvolge l'array originale e modificandolo modifica l'array originale. Ecco perché non è possibile aggiungere o rimuovere, poiché le matrici hanno dimensioni fisse.
Nand,

@Non sono sicuro di cosa stavo pensando, ma guardando il codice sorgente, in effetti il ​​metodo Arrays.asList crea un ArrayList supportato dall'array specificato. Grazie per segnalarlo. Eliminato il mio commento precedente (impossibile modificarlo).
Timmos,

100

Ecco una funzione di array shuffle Fisher – Yates funzionante ed efficiente:

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

o

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
Votato perché avevo bisogno di una soluzione che non avesse il sovraccarico di creare una raccolta di
numeri

2
La seconda implementazione non ha il potenziale per scambiare con il proprio indice? random.nextInt(int bound)è esclusivo ma fornirlo i + 1come argomento consentirebbe indexe ipotrebbe essere potenzialmente lo stesso.
bmcentee148,

21
@ bmcentee148 Lo scambio di un elemento con se stesso è consentito in un ordine casuale. Non capirlo ha indebolito l'Enigma e ha aiutato Alan Turing a risolverlo. en.wikipedia.org/wiki/…
Ellen Spertus,

4
Il xortrucco è ottimo per scambiare i registri della CPU quando la CPU non ha istruzioni di scambio e non ci sono registri gratuiti, ma per scambiare gli elementi dell'array all'interno di un ciclo, non vedo alcun vantaggio. Per le variabili locali temporanee, non vi è motivo di dichiararle al di fuori del ciclo.
Holger,

1
È leggermente più efficiente dichiarare la tempvariabile al di fuori del ciclo. Il XORtrucco dovrebbe essere più veloce dell'uso di una tempvariabile, ma l'unico modo per essere sicuri di eseguire un test di riferimento.
Dan Bray,

25

La classe Collections ha un metodo efficiente per mescolare, che può essere copiato, in modo da non dipendere da esso:

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

per non dipendere da esso ? Preferirei di gran lunga dipenderne, se fosse possibile.
shmosel,

@shmosel Allora sentiti libero di usarlo. Assicurarsi di importare la classe richiesta e di aver convertito l'array in un elenco con Arrays.asList. Devi anche convertire la lista risultante in un array
KitKat

Non è possibile utilizzare Arrays.asList()su un array primitivo. E non avresti bisogno di riconvertirlo perché è solo un wrapper.
Shmosel,

13

Guarda la Collectionslezione, in particolare shuffle(...).


8
Come usi questa classe Collezioni in Android? È necessario eseguire un'importazione speciale (CRTL SHIFT O non funziona) per utilizzarla?
Hubert,

@Hubert dovrebbe essere parte del pacchetto java.util. Fa parte della libreria standard dalla v1.2.
MauganRa,

3
Per rendere la tua risposta più autonoma, dovrebbe contenere un codice di esempio. IE:import java.util.Collections; shuffle(solutionArray);
Stevoisiak,

10

Ecco una soluzione completa usando l' Collections.shuffleapproccio:

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

Si noti che soffre a causa dell'incapacità di Java di tradurre senza problemi tra int[]e Integer[](e quindi int[]e List<Integer>).


10

Hai un paio di opzioni qui. Un elenco è un po 'diverso da un array quando si tratta di mescolare.

Come puoi vedere di seguito, un array è più veloce di un elenco e un array primitivo è più veloce di un array di oggetti.

Durate del campione

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

Di seguito, ci sono tre diverse implementazioni di uno shuffle. Dovresti usare Collections.shuffle solo se hai a che fare con una collezione. Non è necessario avvolgere l'array in una raccolta solo per ordinarlo. I metodi seguenti sono molto semplici da implementare.

ShuffleUtil Class

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;

Metodo principale

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

Mescolare un elenco generico

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

Mescolare un array generico

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

Mescolare una matrice primitiva

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

Metodi di utilità

Semplici metodi di utilità per copiare e convertire array in elenchi e viceversa.

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

Classe di portata

Genera un intervallo di valori, simile alla rangefunzione di 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");
                }
            };
        }
    }
}

1
Non stai programmando le stesse cose e cronometri una sola volta (quindi il loro ordine conta e dimentichi l'ottimizzazione del tempo di esecuzione). Dovresti chiamare range, toArraye toPrimitiveprima di ogni tempismo, e ripetere il ciclo per essere in grado di concludere qualsiasi cosa (pseudo-codice: fai diverse volte {genera lista, arr e iarr; lista di shuffle, tempo di shuffle e arma di shuffle;) Il mio risultato: 1 °: list: 36017ns, arr: 28262ns, iarr: 23334ns. 100 °: list: 18445ns, arr: 19995ns, iarr: 18657ns. Mostra solo che int [] è pre-ottimizzato (per codice) ma sono quasi equivalenti all'ottimizzazione del runtime.
syme

9

L'utilizzo ArrayList<Integer>può aiutarti a risolvere il problema del mescolamento senza applicare molta logica e consumando meno tempo. Ecco cosa suggerisco:

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

Probabilmente non quest'ultimo, che richiede meno tempo . In effetti, questo è certamente più lento delle precedenti implementazioni.
Boris the Spider,

1
Per qualcuno che copia il codice, guarda "per ciclo" i = 1 forse hai bisogno di i = 0
Boris Karloff


5

Puoi usare java 8 ora:

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

2
Non c'è nulla di specifico di Java8 in questo codice. Funziona da Java2. Bene, funzionerebbe, una volta risolta l'incoerenza tra il primo utilizzo liste il riferimento improvviso cardsList. Ma poiché è necessario creare il temporaneo list, che è stato omesso, non vi è alcun vantaggio rispetto Collections.shuffle(Arrays.asList(arr));all'approccio mostrato più volte qui. Che funziona anche da Java2.
Holger,

3

Ecco una versione di Generics per gli 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;
        }
    }
}

Considerando che ArrayList è fondamentalmente solo un array, può essere consigliabile lavorare con un ArrayList invece che con l'array esplicito e utilizzare Collections.shuffle (). I test delle prestazioni, tuttavia, non mostrano alcuna differenza significativa tra quanto sopra e 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

L'implementazione di Apache Commons MathArrays.shuffle è limitata a int [] e la penalità delle prestazioni è probabilmente dovuta al generatore di numeri casuali utilizzato.


1
Sembra che tu possa passare new JDKRandomGenerator()a MathArrays.shuffle. Mi chiedo come ciò influisca sulle prestazioni?
Brandon,

A dire il vero ... sembra che MathArrays#shuffleha una dotazione nel suo ciclo di base: int targetIdx = new UniformIntegerDistribution(rng, start, i).sample();. Bizzarro.
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;
}

A proposito, ho notato che questo codice restituisce un ar.length - 1numero di elementi, quindi se il tuo array ha 5 elementi, il nuovo array mischiato avrà 4 elementi. Questo accade perché dice il ciclo for i>0. Se cambi in i>=0, ottieni tutti gli elementi mescolati.


Solo un avvertimento, potresti voler spostare questo nella sezione dei commenti della tua domanda, poiché probabilmente verrà contrassegnato se viene lasciato come propria risposta.
Jason D,

1
Questo sembra rispondere alla domanda, quindi non sono sicuro di cosa tu stia parlando @JasonD
Sumurai8

1
Il codice è corretto, il commento è sbagliato. Se cambi i>0a i>=0, perdi tempo scambiando l'elemento 0con se stesso.
jcsahnwaldt Ripristina Monica il

3

Ecco una soluzione che utilizza Apache Commons Math 3.x (solo per 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 [])

In alternativa, Apache Commons Lang 3.6 ha introdotto nuovi metodi shuffle nella ArrayUtilsclasse (per oggetti e qualsiasi tipo primitivo).

ArrayUtils.shuffle(array);

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


3

Ho visto alcune informazioni mancanti in alcune risposte, quindi ho deciso di aggiungerne uno nuovo.

Java collezioni Arrays.asList prende var-arg di tipo T (T ...). Se si passa un array primitivo (int array), il metodo asList inferirà e genererà unList<int[]> , che è un elenco di un elemento (l'unico elemento è l'array primitivo). se mescoli questo elenco di elementi, non cambierà nulla.

Quindi, prima devi convertire il tuo array primitivo in array di oggetti Wrapper. per questo puoi usare il ArrayUtils.toObjectmetodo da apache.commons.lang. quindi passa l'array generato a un elenco e infine rimescola quello.

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

3

Ecco un altro modo per mescolare un elenco

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

Scegli un numero casuale dall'elenco originale e salvalo in un altro elenco, quindi rimuovi il numero dall'elenco originale. Le dimensioni dell'elenco originale continueranno a diminuire di uno fino a quando tutti gli elementi non vengono spostati nel nuovo elenco.


2

Una soluzione semplice per Groovy:

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

Ciò ordinerà casualmente tutti gli elementi dell'elenco di array che archivia il risultato desiderato mescolando tutti gli elementi.



1

Sto valutando questa domanda molto popolare perché nessuno ha scritto una versione shuffle-copy. Lo stile è fortemente preso in prestito Arrays.java, perché chi non sta saccheggiando la tecnologia Java in questi giorni? Generico e intimplementazioni incluse.

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

Questo è l'algoritmo 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]);
    }
}

1

C'è anche un altro modo, non ancora pubblicato

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

in questo modo più facile, dipendeva dal contesto


1

La soluzione più semplice per questo mescolamento casuale in un 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]);
}

1
  1. Box da int[]aInteger[]
  2. Avvolgere un array in un elenco con il Arrays.asListmetodo
  3. Mischia con il Collections.shufflemetodo

    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

Codice più semplice da mescolare:

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

Utilizzando la classe casuale

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

Aggiungi una descrizione relativa alla tua risposta.
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

simile senza usare 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);

0

Una delle soluzioni sta usando la permutazione per pre-calcolare tutte le permutazioni e memorizzata nella ArrayList

Java 8 ha introdotto un nuovo metodo, ints (), nella classe java.util.Random. Il metodo ints () restituisce un flusso illimitato di valori int pseudocasuali. È possibile limitare i numeri casuali tra un intervallo specificato fornendo i valori minimo e massimo.

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

Con l'aiuto della generazione del numero casuale, è possibile scorrere il ciclo e scambiare con l'indice corrente con il numero casuale. Ecco come è possibile generare un numero casuale con complessità spaziale O (1).


0

Senza soluzione casuale:

   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));
    }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.