Aléatoire d'un tableau de brassage

J'ai besoin de mélanger aléatoirement le tableau suivant:

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

Y a-t-il une fonction pour le faire?

185
demandé sur leventov 2009-10-05 16:15:59

25 réponses

Utiliser des Collections pour mélanger un tableau de types primitifs est un peu exagéré...

Il est assez simple d'implémenter la fonction vous-même, en utilisant par exemple le 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;
    }
  }
}
232
répondu PhiLho 2015-10-02 07:30:10

Voici un moyen simple d'utiliser un ArrayList:

List<Integer> solution = new ArrayList<>();
for (int i = 1; i <= 6; i++) {
    solution.add(i);
}
Collections.shuffle(solution);
133
répondu methodin 2017-01-05 01:13:10

Voici une fonction de tableau aléatoire Fisher-Yates qui fonctionne et qui est efficace:

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

Ou

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;
    }
}
89
répondu Dan Bray 2016-11-10 11:11:16

Collections classe a une méthode efficace pour mélanger, qui peut être copié, afin de ne pas en dépendre:

/**
 * 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;
    }
}
20
répondu KitKat 2018-06-09 16:46:53

Oeil à la Collections classe, spécifiquement shuffle(...).

12
répondu Dave 2017-01-05 01:13:41

Voici une solution complète utilisant l'approche 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);
  }    
}

Notez qu'il souffre de L'incapacité de Java à traduire en douceur entre int[] et Integer[] (et donc int[] et List<Integer>).

9
répondu Duncan Jones 2014-01-30 10:50:06

Vous avez quelques options ici. Une liste est un peu différente d'un tableau quand il s'agit de mélanger.

Comme vous pouvez le voir ci-dessous, un tableau est plus rapide qu'une liste, et un tableau primitif est plus rapide qu'un tableau d'objets.

Durée Des Échantillons

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

Ci-Dessous, sont trois implémentations différentes d'un shuffle. Vous ne devez utiliser que des Collections.shuffle si vous avez affaire à une collection. Il n'est pas nécessaire d'envelopper votre tableau dans une collection juste pour faire le tri. Le les méthodes ci-dessous sont très simples à mettre en œuvre.

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

Méthode 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);
    }

Mélanger une liste générique

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

Mélanger un tableau Générique

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

Mélanger un tableau 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;
    }

Méthodes D'Utilité

Méthodes utilitaires simples pour copier et convertir des tableaux en listes et vice-versa.

    // ================================================================
    // 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 De Plage

Génère une plage de valeurs, similaire à la fonction range de 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");
                }
            };
        }
    }
}
9
répondu Mr. Polywhirl 2015-11-30 20:39:45

L'utilisation de ArrayList<Integer> peut vous aider à résoudre le problème du brassage sans appliquer beaucoup de logique et consommer moins de temps. Voici ce que je suggère:

ArrayList<Integer> x = new ArrayList<Integer>();
for(int i=1; i<=add.length(); i++)
{
    x.add(i);
}
Collections.shuffle(x);
8
répondu SalmaanKhan 2014-11-24 13:12:44

Le code suivant permettra d'obtenir un ordre aléatoire sur le tableau.

// Shuffle the elements in the array
Collections.shuffle(Arrays.asList(array));

À Partir de: http://www.programcreek.com/2012/02/java-method-to-shuffle-an-int-array-with-random-order/

6
répondu Rajib Biswas 2016-08-02 06:16:39

Vous pouvez utiliser java 8 Maintenant:

Collections.addAll(list, arr);
Collections.shuffle(list);
cardsList.toArray(arr);
4
répondu Иван Николайчук 2016-04-24 11:12:26

Voici une version générique pour les tableaux:

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

Considérant que ArrayList est fondamentalement juste un tableau, il peut être conseillé de travailler avec un ArrayList au lieu du tableau explicite et d'utiliser des Collections.shuffle(). Cependant, les tests de Performance ne montrent aucune différence significative entre ce qui précède et les Collections.trier ():

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

Les MathArrays d'implémentation D'Apache Commons.shuffle est limité à int [] et la pénalité de performance est probablement due au générateur de nombres aléatoires utilisé.

3
répondu user1050755 2014-11-04 08:05:36
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;
}

En passant, j'ai remarqué que ce code renvoie un nombre ar.length - 1 d'éléments, donc si votre tableau a 5 éléments, le nouveau tableau mélangé aura 4 éléments. Cela se produit parce que la boucle for dit i>0. Si vous changez pour i>=0, vous obtenez tous les éléments mélangés.

3
répondu Cristiane Dos Santos Costa 2014-11-15 16:53:30

Voici une solution utilisant Apache Commons Math 3.x (pour les tableaux int[] uniquement):

MathArrays.shuffle(array);

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

Alternativement, Apache Commons Lang 3.6 a introduit de nouvelles méthodes de lecture aléatoire dans la classe ArrayUtils (pour les objets et toute primitive type).

ArrayUtils.shuffle(array);

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

2
répondu Emmanuel Bourg 2017-07-19 19:58:53

J'ai vu des informations manquantes dans certaines réponses, alors j'ai décidé d'en ajouter une nouvelle.

Tableaux de collections Java.asList prend var-arg de type T (T ...). Si vous passez un tableau primitif (tableau int), la méthode asList déduira et générera un List<int[]>, qui est une liste d'un élément(l'élément est le tableau primitif). si vous mélangez cette liste d'éléments, cela ne changera rien.

Donc, vous devez d'abord convertir votre tableau primitif en tableau d'objets Wrapper. pour cela, vous pouvez utiliser ArrayUtils.toObject méthode de apache.commun.lang. ensuite, passez le tableau généré à une liste et mélangez-le finalement.

  int[] intArr = {1,2,3};
  List<Integer> integerList = Arrays.asList(ArrayUtils.toObject(array));
  Collections.shuffle(integerList);
  //now! elements in integerList are shuffled!
2
répondu NԀƎ 2017-07-26 10:59:22
  1. Boîte de int[] à Integer[]
  2. enveloppe un tableau dans une liste avec la méthode Arrays.asList
  3. Mélanger avec Collections.shuffle méthode

    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]
    
2
répondu YujiSoftware 2018-02-17 10:22:01

Voici une autre façon de mélanger une liste

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

Choisissez un nombre aléatoire dans la liste d'origine et enregistrez - le dans une autre liste.Retirez ensuite le numéro de la liste d'origine.La taille de la liste d'origine continuera à diminuer d'un jusqu'à ce que tous les éléments soient déplacés vers la nouvelle liste.

2
répondu PS5 2018-07-12 19:58:26

Je pèse sur cette question très populaire parce que personne n'a écrit une version aléatoire. Le Style est fortement emprunté à Arrays.java, Car Qui ne pille pas la technologie Java ces jours-ci? Implémentations génériques et int incluses.

   /**
    * 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
répondu QED 2016-05-31 21:26:59

C'est l'algorithme 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
répondu BufBills 2016-08-15 14:57:09

Il y a aussi un autre moyen, pas encore post

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

De Cette façon plus facile, dépendait du contexte

1
répondu Marcelo Ferreira 2016-10-27 17:42:56

La solution la plus simple pour ce brassage aléatoire dans un tableau.

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
répondu Archit Goel 2017-07-05 08:33:50

Une solution simple pour Groovy:

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

Cela va trier tous les éléments de la liste de tableau au hasard qui Archive le résultat souhaité de mélanger tous les éléments.

1
répondu Hans Kristian 2017-12-07 07:49:29

Code le plus simple à mélanger:

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
répondu suraj 2018-04-06 10:23:39
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
répondu nikhil gupta 2017-09-26 12:56:42
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
répondu aurobind singh 2018-06-28 05:27:43

Un autre moyen facile de mélanger:

int LengthArray = solutionArray.lenght();
Random r = new Random();
int randomNumber = r.nextInt(LengthArray);
Integer Chosen = solutionArray.getInteger(randomNumber);
0
répondu aomerk 2018-07-12 22:00:24