Je dois mélanger au hasard le tableau suivant:
int[] solutionArray = {1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1};
Y a-t-il une fonction pour faire ça?
Utiliser Collections pour mélanger un tableau de types primitifs est un peu exagéré ...
Il est assez simple de mettre en oeuvre 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;
}
}
}
Voici un moyen simple en utilisant une ArrayList
:
List<Integer> solution = new ArrayList<>();
for (int i = 1; i <= 6; i++) {
solution.add(i);
}
Collections.shuffle(solution);
Voici une fonction réseau efficace et efficace de Fisher – Yates:
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;
}
}
Collections class a une méthode efficace pour mélanger, qui peut être copiée pour 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;
}
}
Regardez la Collections
class, en particulier shuffle(...)
.
Vous avez deux 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.
List<Integer> Shuffle: 43133ns
Integer[] Shuffle: 31884ns
int[] Shuffle: 25377ns
Ci-dessous, trois implémentations différentes d'un mélange. Vous ne devriez utiliser Collections.shuffle que si vous avez affaire à une collection. Il n'est pas nécessaire de placer votre tableau dans une collection simplement pour le trier. Les méthodes ci-dessous sont très simples à mettre en œuvre.
import Java.lang.reflect.Array;
import Java.util.*;
public class ShuffleUtil<T> {
private static final int[] EMPTY_INT_ARRAY = new int[0];
private static final int SHUFFLE_THRESHOLD = 5;
private static Random Rand;
public static void main(String[] args) {
List<Integer> list = null;
Integer[] arr = null;
int[] iarr = null;
long start = 0;
int cycles = 1000;
int n = 1000;
// Shuffle List<Integer>
start = System.nanoTime();
list = range(n);
for (int i = 0; i < cycles; i++) {
ShuffleUtil.shuffle(list);
}
System.out.printf("%22s: %dns%n", "List<Integer> Shuffle", (System.nanoTime() - start) / cycles);
// Shuffle Integer[]
start = System.nanoTime();
arr = toArray(list);
for (int i = 0; i < cycles; i++) {
ShuffleUtil.shuffle(arr);
}
System.out.printf("%22s: %dns%n", "Integer[] Shuffle", (System.nanoTime() - start) / cycles);
// Shuffle int[]
start = System.nanoTime();
iarr = toPrimitive(arr);
for (int i = 0; i < cycles; i++) {
ShuffleUtil.shuffle(iarr);
}
System.out.printf("%22s: %dns%n", "int[] Shuffle", (System.nanoTime() - start) / cycles);
}
// ================================================================
// Shuffle List<T> (Java.lang.Collections)
// ================================================================
@SuppressWarnings("unchecked")
public static <T> void shuffle(List<T> list) {
if (Rand == null) {
Rand = new Random();
}
int size = list.size();
if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
for (int i = size; i > 1; i--) {
swap(list, i - 1, Rand.nextInt(i));
}
} else {
Object arr[] = list.toArray();
for (int i = size; i > 1; i--) {
swap(arr, i - 1, Rand.nextInt(i));
}
ListIterator<T> it = list.listIterator();
int i = 0;
while (it.hasNext()) {
it.next();
it.set((T) arr[i++]);
}
}
}
public static <T> void swap(List<T> list, int i, int j) {
final List<T> l = list;
l.set(i, l.set(j, l.get(i)));
}
public static <T> List<T> shuffled(List<T> list) {
List<T> copy = copyList(list);
shuffle(copy);
return copy;
}
// ================================================================
// Shuffle T[]
// ================================================================
public static <T> void shuffle(T[] arr) {
if (Rand == null) {
Rand = new Random();
}
for (int i = arr.length - 1; i > 0; i--) {
swap(arr, i, Rand.nextInt(i + 1));
}
}
public static <T> void swap(T[] arr, int i, int j) {
T tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public static <T> T[] shuffled(T[] arr) {
T[] copy = Arrays.copyOf(arr, arr.length);
shuffle(copy);
return copy;
}
// ================================================================
// Shuffle int[]
// ================================================================
public static <T> void shuffle(int[] arr) {
if (Rand == null) {
Rand = new Random();
}
for (int i = arr.length - 1; i > 0; i--) {
swap(arr, i, Rand.nextInt(i + 1));
}
}
public static <T> void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public static int[] shuffled(int[] arr) {
int[] copy = Arrays.copyOf(arr, arr.length);
shuffle(copy);
return copy;
}
Méthodes 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;
}
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");
}
};
}
}
}
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 int[]
et Integer[]
(et donc int[]
et List<Integer>
).
Utiliser ArrayList<Integer>
peut vous aider à résoudre le problème du brassage sans appliquer beaucoup de logique et prendre 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);
Le code suivant réalisera un ordre aléatoire sur le tableau.
// Shuffle the elements in the array
Collections.shuffle(Arrays.asList(array));
de: http://www.programcreek.com/2012/02/Java-method-to-shuffle-an-int-array-with-random-order/
Vous pouvez utiliser Java 8 maintenant:
Collections.addAll(list, arr);
Collections.shuffle(list);
cardsList.toArray(arr);
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 qu'ArrayList est fondamentalement juste un tableau, il peut être conseillé de travailler avec ArrayList au lieu du tableau explicite et d'utiliser Collections.shuffle (). Cependant, les tests de performance ne montrent aucune différence significative entre ce qui précède et 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'implémentation MathArrays.shuffle d'Apache Commons est limitée à int [] et la pénalité de performance est probablement due au générateur de nombres aléatoires utilisé.
Voici une solution utilisant Apache Commons Math 3.x (pour les tableaux int [] uniquement):
MathArrays.shuffle(array);
Sinon, Apache Commons Lang 3.6 a introduit de nouvelles méthodes de mélange dans la classe ArrayUtils
(pour les objets et tout type de primitive).
ArrayUtils.shuffle(array);
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 propos, j'ai remarqué que ce code renvoyait un nombre d'éléments ar.length - 1
; si votre tableau contient 5 éléments, le nouveau tableau mélangé en aura 4. Cela se produit parce que la boucle for dit i>0
. Si vous passez à i>=0
, tous les éléments sont mélangés.
J'ai vu des informations manquantes dans certaines réponses, alors j'ai décidé d'en ajouter une nouvelle.
Collections Java Arrays.asList prend un var-arg de type T (T ...)
. Si vous passez un tableau primitif (int array), la méthode asList en déduira et générera un List<int[]>
, qui est une liste à un élément (l'élément unique est le tableau primitif). Si vous mélangez cette liste d’éléments, elle ne changera rien.
Donc, vous devez d’abord convertir votre tableau primitif en tableau d’objets Wrapper. Pour cela, vous pouvez utiliser la méthode ArrayUtils.toObject
d'Apache.commons.lang. puis passez le tableau généré à une liste et mélangez-le enfin.
int[] intArr = {1,2,3};
List<Integer> integerList = Arrays.asList(ArrayUtils.toObject(array));
Collections.shuffle(integerList);
//now! elements in integerList are shuffled!
int[]
à Integer[]
Arrays.asList
Mélanger avec la méthode Collections.shuffle
int[] solutionArray = { 1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1 };
Integer[] boxed = Arrays.stream(solutionArray).boxed().toArray(Integer[]::new);
Collections.shuffle(Arrays.asList(boxed));
System.out.println(Arrays.toString(boxed));
// [1, 5, 5, 4, 2, 6, 1, 3, 3, 4, 2, 6]
Voici un autre moyen 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.Ensuite, supprimez le numéro de la liste d'origine.La taille de la liste d'origine continuera à diminuer d'un élément jusqu'à ce que tous les éléments soient déplacés vers la nouvelle liste.
Une solution simple pour Groovy:
solutionArray.sort{ new Random().nextInt() }
Cela triera aléatoirement tous les éléments de la liste de tableaux qui archive le résultat souhaité du brassage de tous les éléments.
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]);
}
Le 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));
}
}
Je me fie à cette question très populaire parce que personne n'a écrit une version en copie aléatoire. Le style est fortement emprunté à Arrays.Java
, car qui n’est pas pillant la technologie Java de nos jours? 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;
}
Il y a une autre façon aussi, pas encore poster
//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épend du contexte
C'est l'algorithme de shuth 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]);
}
}
Une des solutions consiste à utiliser la permutation pour pré-calculer toutes les permutations et les stocker dans la liste ArrayList.
Java 8 a introduit une nouvelle méthode, ints (), dans la classe Java.util.Random. La méthode ints () renvoie un flux illimité de valeurs int pseudo-aléatoires. Vous pouvez limiter les nombres aléatoires entre une plage spécifiée en fournissant les valeurs minimale et maximale.
Random genRandom = new Random();
int num = genRandom.nextInt(arr.length);
Avec l’aide de la génération du nombre aléatoire, vous pouvez parcourir la boucle et permuter avec l’index en cours avec le nombre aléatoire .. C’est ainsi que vous pouvez générer un nombre aléatoire avec une complexité d’espace O(1).
L'utilisation de Ints.asList()
de Guava est aussi simple que:
Collections.shuffle(Ints.asList(array));
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);
}
}
}
similaire sans utiliser 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);
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);
}
}