metodo - shuffle array javascript
Mezcla aleatoria de una matriz (23)
- Cuadro de
int[]
aInteger[]
- Envuelva una matriz en una lista con el método
Arrays.asList
Mezclar con el método
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]
Necesito mezclar aleatoriamente la siguiente matriz:
int[] solutionArray = {1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1};
¿Hay alguna función para hacer eso?
Aquí hay otra manera de barajar una lista
public List<Integer> shuffleArray(List<Integer> a) {
List<Integer> b = new ArrayList<Integer>();
while (a.size() != 0) {
int random = (int) (Math.random() * (a.size()));
b.add(a.get(random));
a.remove(a.get(random));
}
return b;
}
Elija un número aleatorio de la lista y guárdelo en otra lista y elimine el número de la lista original.
Aquí hay una función de matriz aleatoria de Fisher-Yates que funciona y es eficiente:
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;
}
}
Aquí hay una manera simple de usar una ArrayList
:
List<Integer> solution = new ArrayList<>();
for (int i = 1; i <= 6; i++) {
solution.add(i);
}
Collections.shuffle(solution);
Aquí hay una solución completa que utiliza el enfoque 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);
}
}
Tenga en cuenta que sufre debido a la incapacidad de Java para traducir sin problemas entre int[]
y Integer[]
(y por lo tanto int[]
y List<Integer>
).
Aquí hay una solución que usa Apache Commons Math 3.x (solo para matrices int []):
MathArrays.shuffle(array);
Alternativamente, Apache Commons Lang 3.6 introdujo nuevos métodos aleatorios para la clase ArrayUtils
(para objetos y cualquier tipo primitivo).
ArrayUtils.shuffle(array);
Aquí hay una versión de Generics para matrices:
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;
}
}
}
Teniendo en cuenta que ArrayList es básicamente una matriz, puede ser aconsejable trabajar con una ArrayList en lugar de la matriz explícita y usar Collections.shuffle (). Sin embargo, las pruebas de rendimiento no muestran ninguna diferencia significativa entre las anteriores y 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
La implementación de Apache Commons MathArrays.shuffle está limitada a int [] y es probable que la penalización de rendimiento se deba al generador de números aleatorios que se está utilizando.
Código más simple para mezclar:
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));
}
}
El siguiente código logrará un orden aleatorio en la matriz.
// Shuffle the elements in the array
Collections.shuffle(Arrays.asList(array));
desde: http://www.programcreek.com/2012/02/java-method-to-shuffle-an-int-array-with-random-order/
El uso de ArrayList<Integer>
puede ayudarlo a resolver el problema de mezclar sin aplicar mucha lógica y consumir menos tiempo. Esto es lo que sugiero:
ArrayList<Integer> x = new ArrayList<Integer>();
for(int i=1; i<=add.length(); i++)
{
x.add(i);
}
Collections.shuffle(x);
Este es el 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]);
}
}
Estoy evaluando esta muy popular pregunta porque nadie ha escrito una versión de copia aleatoria. El estilo es prestado en gran medida de Arrays.java
, porque ¿quién no está saqueando la tecnología Java en estos días? Implementaciones genéricas e int
incluidas.
/**
* 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;
}
Hay otra manera también, no publicar aún
//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 esa manera más fácil, dependía del contexto
La clase de colecciones tiene un método eficiente para mezclar, que se puede copiar, para no depender de ello:
/**
* 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;
}
}
La solución más simple para este Random Shuffling en una matriz.
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]);
}
Mire la clase Collections
, específicamente shuffle(...)
.
Puedes usar java 8 ahora:
Collections.addAll(list, arr);
Collections.shuffle(list);
cardsList.toArray(arr);
Tienes un par de opciones aquí. Una lista es un poco diferente a una matriz cuando se trata de barajar.
Como puede ver a continuación, una matriz es más rápida que una lista, y una matriz primitiva es más rápida que una matriz de objetos.
Duraciones de la muestra
List<Integer> Shuffle: 43133ns
Integer[] Shuffle: 31884ns
int[] Shuffle: 25377ns
A continuación, hay tres implementaciones diferentes de una mezcla. Solo debe usar Collections.shuffle si está tratando con una colección. No hay necesidad de envolver su matriz en una colección solo para ordenarla. Los métodos a continuación son muy simples de implementar.
Clase 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étodo principal
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);
}
Mezclar una lista genérica
// ================================================================
// 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;
}
Mezclar una matriz genérica
// ================================================================
// 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;
}
Mezclar una matriz 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;
}
Métodos de utilidad
Métodos simples de utilidad para copiar y convertir matrices en listas y 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;
}
Clase de rango
Genera un rango de valores, similar a la función de 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");
}
};
}
}
}
Una solución simple para Groovy:
solutionArray.sort{ new Random().nextInt() }
Esto ordenará aleatoriamente todos los elementos de la lista de arreglo que archiva el resultado deseado de mezclar todos los elementos.
Usar colecciones para barajar una matriz de tipos primitivos es un poco exagerado ...
Es lo suficientemente simple como para implementar la función usted mismo, utilizando, por ejemplo, la combinación aleatoria de 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;
}
}
}
Vi algunas extrañas información en algunas respuestas, así que decidí agregar una nueva.
Las colecciones Java Arrays.asList toman var-arg de tipo T (T ...)
. Si pasa una matriz primitiva (matriz int), el método asList inferirá y generará una List<int[]>
, que es una lista de un elemento (el elemento uno es la matriz primitiva). si barajas esta lista de un elemento, no cambiará nada.
Entonces, primero tienes que convertir tu matriz primitiva en matriz de objetos Wrapper. para esto puedes usar el método ArrayUtils.toObject
de apache.commons.lang. luego pasa la matriz generada a una lista y finalmente baraja eso.
int[] intArr = {1,2,3};
List<Integer> integerList = Arrays.asList(ArrayUtils.toObject(array));
Collections.shuffle(integerList);
//now! elements in integerList are shuffled!
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;
}
Por cierto, me he dado cuenta de que este código devuelve un ar.length - 1
número de elementos, por lo que si su matriz tiene 5 elementos, la nueva matriz mezclada tendrá 4 elementos. Esto sucede porque el ciclo for dice i>0
. Si cambias a i>=0
, obtienes todos los elementos mezclados.
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);
}
}
}