Aleatório aleatório de uma matriz


232

Preciso embaralhar aleatoriamente a seguinte matriz:

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

Existe alguma função para fazer isso?


5
Este é o método SDK que você está procurando Collections.shuffle (Arrays.asList (array));
Louis Hong

2
@ Louisie Não, isso não funciona. Isso criaria uma List<int[]>entrada contendo uma. Veja minha resposta para saber como usar isso Collections.shuffle().
Duncan Jones

2
Não é realmente uma resposta para a pergunta original, mas MathArrays.shuffle da biblioteca commons-math3 faz o trabalho.
Sandris

1
Isso não é suficiente para garantir uma resposta, mas lembro-me de um artigo muito interessante do livro "Graphics Gems", que falava sobre atravessar uma matriz em ordem pseudo-aleatória. Na minha opinião, é melhor do que ter que embaralhar os dados em primeiro lugar. A implementação C é encontrada aqui github.com/erich666/GraphicsGems/blob/master/gems/Dissolve.c
Lennart Rolland

Veja também esta questão intimamente relacionados: stackoverflow.com/questions/2450954/...
Pierz

Respostas:


263

Usar Coleções para embaralhar uma matriz de tipos primitivos é um exagero ...

É simples o suficiente para implementar a função você mesmo, usando, por exemplo, o shuffle 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;
    }
  }
}

26
Nitpick extremamente trivial, mas você pode simplesmente usar em println()vez de println(""). Mais claro na intenção Eu acho que :)
Cowan

55
Seria muito melhor usar Collections.shuffle (Arrays.asList (array)); então, fazendo um baralhamento.
Louis Hong

21
@ Louisie Collections.shuffle(Arrays.asList(array))não funciona, porque Arrays.asList(array)retorna Collection<int[]>não Collection<Integer>como você pensava.
Adam Stelmaszczyk

15
@exhuma Porque se você tem uma matriz de milhares ou milhões de valores primitivos para classificar, agrupar cada um em um objeto apenas para fazer uma classificação é um pouco caro, tanto na memória quanto na CPU.
PhiLho

14
Este não é o embaralhamento de Fisher-Yates. Isso se chama shuffle de Durstenfeld . O shuffle original dos pescadores corre em O (n ^ 2), o que é extremamente lento.
Pacerier

164

Aqui está uma maneira simples de usar ArrayList:

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

1
Você pode simplesmenteCollectons.shuffle(Arrays.asList(solutionArray));
FindOutIslamNow 23/01

@ Timmos Você está errado. Arrays.asList envolve a matriz original e, assim, modificá-la modifica a matriz original. É por isso que você não pode adicionar ou remover, porque as matrizes são de tamanho fixo.
Nand

@ Não tenho certeza do que eu estava pensando, mas olhando para o código-fonte, de fato o método Arrays.asList cria um ArrayList apoiado pelo array especificado. Obrigado por apontar isso. Excluiu meu comentário anterior (não foi possível editá-lo).
Timmos

100

Aqui está uma função funcional e eficiente da matriz de embaralhamento 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;
    }
}

1
Votado até porque eu precisava de uma solução que não tinha a alta sobrecarga de criar uma coleção de Integer
mwk

2
A segunda implementação não tem o potencial de trocar com seu próprio índice? random.nextInt(int bound)é exclusivo, mas apresentá-lo i + 1como argumento permitiria indexe ipotencialmente seria o mesmo.
bmcentee148

21
@ bmcentee148 Trocar um elemento consigo mesmo é permitido em uma ordem aleatória. Não entender isso enfraqueceu o Enigma e ajudou a habilitar Alan Turing a quebrá-lo. en.wikipedia.org/wiki/…
Ellen Spertus

4
O xortruque é ótimo para trocar registros de CPU quando a CPU não possui instruções de troca e não há registros livres, mas para trocar elementos de matriz dentro de um loop, não vejo nenhum benefício. Para as variáveis ​​locais temporárias, não há motivo para declará-las fora do loop.
Holger

1
É um pouco mais eficiente declarar a tempvariável fora do loop. O XORtruque deve ser mais rápido do que usar uma tempvariável, mas a única maneira de garantir que ele realize um teste de benchmark.
Dan Bray

25

A classe Collections possui um método eficiente para embaralhar, que pode ser copiado, para não depender dela:

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

para não depender disso ? Eu preferiria depender disso, se isso fosse possível.
shmosel

@shmosel Então fique à vontade para usá-lo. Certifique-se de importar a classe necessária e de ter convertido a matriz em uma lista Arrays.asList. Você tem que converter a lista resultante para uma matriz, também
KitKat

Você não pode usar Arrays.asList()em uma matriz primitiva. E você não precisaria convertê-lo novamente, porque é apenas um invólucro.
shmosel

13

Olhe para a Collectionsclasse, especificamente shuffle(...).


8
Como você usa essa classe de coleções no Android? Você precisa fazer uma importação especial (CRTL SHIFT O não funciona) para usá-la?
Hubert

@Hubert deve fazer parte do pacote java.util . Faz parte da biblioteca padrão desde a v1.2.
MauganRa

3
Para tornar sua resposta mais independente, ela deve conter código de exemplo. IE:import java.util.Collections; shuffle(solutionArray);
Stevoisiak

10

Aqui está uma solução completa usando a Collections.shuffleabordagem:

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

Observe que ele sofre devido à incapacidade do Java de traduzir suavemente entre int[]e Integer[](e, portanto, int[]e List<Integer>).


10

Você tem algumas opções aqui. Uma lista é um pouco diferente de uma matriz quando se trata de embaralhar.

Como você pode ver abaixo, uma matriz é mais rápida que uma lista e uma matriz primitiva é mais rápida que uma matriz de objetos.

Durações da amostra

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

Abaixo, há três implementações diferentes de um shuffle. Você só deve usar Collections.shuffle se estiver lidando com uma coleção. Não há necessidade de agrupar sua matriz em uma coleção apenas para classificá-la. Os métodos abaixo são muito simples de implementar.

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

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

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

Baralhar uma 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 utilidade

Métodos utilitários simples para copiar e converter matrizes em listas e 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 alcance

Gera um intervalo de valores, semelhante à rangefunção do 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
Você não está cronometrando as mesmas coisas e cronometrando cada uma delas apenas uma vez (a ordem deles conta e você esquece a otimização do tempo de execução). Você deve chamar range, toArraye toPrimitiveantes de qualquer tempo, e fazer um loop para poder concluir qualquer coisa (pseudo-código: faça várias vezes {gerar lista, arr e iarr; lista de embaralhamento de tempo; arr embaralhamento de tempo; arr embaralhamento de tempo; iarr de embaralhamento de tempo}). Meu resultados: 1: list: 36017ns, arr: 28262ns, iarr: 23334ns. 100: list: 18445ns, arr: 19995ns, iarr: 18657ns. Isso apenas mostra que int [] é pré-otimizado (por código), mas eles são quase equivalentes à otimização de tempo de execução.
Syre

9

Usar ArrayList<Integer>pode ajudá-lo a resolver o problema de embaralhar sem aplicar muita lógica e consumir menos tempo. Aqui está o que eu sugiro:

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

Provavelmente não o último - consumindo menos tempo . De fato, isso é certamente mais lento que as implementações primitivas acima.
Boris the Spider

1
Para alguém copia o código, assistir ao "para o ciclo" i = 1 talvez você precisa i = 0
Boris Karloff


5

Você pode usar o java 8 agora:

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

2
Não há nada específico do Java8 nesse código. Isso funciona desde o Java2. Bem, funcionaria, uma vez que você conserte a inconsistência entre o primeiro uso liste a referência repentina cardsList. Mas como você precisa criar o temporário list, que você omitiu, não há benefício sobre a Collections.shuffle(Arrays.asList(arr));abordagem mostrada várias vezes aqui. O que também funciona desde o Java2.
Holger

3

Aqui está uma versão genérica para matrizes:

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 que ArrayList é basicamente apenas uma matriz, pode ser aconselhável trabalhar com uma ArrayList em vez da matriz explícita e usar Collections.shuffle (). Os testes de desempenho, no entanto, não mostram nenhuma diferença significativa entre os itens acima 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

A implementação do Apache Commons MathArrays.shuffle é limitada a int [] e a penalidade de desempenho provavelmente se deve ao uso do gerador de números aleatórios.


1
Parece que você pode passar new JDKRandomGenerator()para MathArrays.shuffle. Gostaria de saber como isso afeta o desempenho?
Brandon

Na verdade ... parece que MathArrays#shuffletem uma alocação em seu núcleo loop: int targetIdx = new UniformIntegerDistribution(rng, start, i).sample();. Bizarro.
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 propósito, notei que esse código retorna ar.length - 1vários elementos; portanto, se sua matriz tiver 5 elementos, a nova matriz aleatória terá 4 elementos. Isso acontece porque o loop for diz i>0. Se você mudar para i>=0, todos os elementos serão embaralhados.


Apenas um aviso, você pode mover isso para a seção de comentários da sua pergunta, pois ela provavelmente será sinalizada se for deixada como sua própria resposta.
Jason D

1
Este parece responder à pergunta, então eu tenho certeza que você está falando sobre @JasonD
Sumurai8

1
O código está correto, o comentário está errado. Se você mudar i>0para i>=0, você perde tempo trocando o elemento 0consigo mesmo.
Jcsahnwaldt Restabelecer Monica

3

Aqui está uma solução usando o Apache Commons Math 3.x (apenas para matrizes 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 [])

Como alternativa, o Apache Commons Lang 3.6 introduziu novos métodos de shuffle na ArrayUtilsclasse (para objetos e qualquer 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

Eu vi algumas informações de falta em algumas respostas, então decidi adicionar uma nova.

Java coleções Arrays.asList leva var-arg do tipo T (T ...). Se você passar uma matriz primitiva (matriz int), o método asList inferirá e gerará a List<int[]>, que é uma lista de um elemento (o elemento único é a matriz primitiva). se você embaralhar esta lista de um elemento, ela não mudará nada.

Portanto, primeiro você precisa converter sua matriz primitiva em matriz de objetos Wrapper. para isso, você pode usar o ArrayUtils.toObjectmétodo apache.commons.lang. depois passe a matriz gerada para uma lista e, finalmente, embaralhe-a.

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

3

Aqui está outra maneira de embaralhar uma lista

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

Escolha um número aleatório da lista original e salve-o em outra lista.Em seguida, remova o número da lista original.O tamanho da lista original continuará diminuindo em um até que todos os elementos sejam movidos para a nova lista.


2

Uma solução simples para Groovy:

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

Isso classificará todos os elementos da lista de matrizes aleatoriamente, arquivando o resultado desejado ao embaralhar todos os elementos.



1

Estou avaliando essa questão muito popular porque ninguém escreveu uma versão aleatória. O estilo é muito emprestado Arrays.java, porque quem não está pilhando a tecnologia Java atualmente? Genérico e intimplementações incluídas.

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

Esse é o algoritmo de shuffle knuth.

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

Existe outra maneira também, ainda não postar

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

assim, mais fácil, dependia do contexto


1

A solução mais simples para este embaralhamento aleatório em uma 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]);
}

1
  1. Caixa de int[]atéInteger[]
  2. Quebrar uma matriz em uma lista com o Arrays.asListmétodo
  3. Aleatório com o Collections.shufflemétodo

    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

Código mais simples para embaralhar:

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

Usando a classe aleatória

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

Adicione uma descrição relacionada à sua resposta.
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

semelhante sem usar 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

Uma das soluções é usar a permutação para pré-calcular todas as permutações e armazenadas no ArrayList

O Java 8 introduziu um novo método, ints (), na classe java.util.Random. O método ints () retorna um fluxo ilimitado de valores int pseudo-aleatórios. Você pode limitar os números aleatórios entre um intervalo especificado, fornecendo os valores mínimo e máximo.

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

Com a ajuda da geração do número aleatório, você pode percorrer o loop e trocar com o índice atual pelo número aleatório. É assim que você pode gerar um número aleatório com complexidade de espaço O (1).


0

Sem solução aleatória:

   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));
    }
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.