Случайная перетасовка массива - PullRequest
204 голосов
/ 05 октября 2009

Мне нужно случайным образом перемешать следующий массив:

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

Есть ли какая-нибудь функция для этого?

Ответы [ 27 ]

3 голосов
/ 26 июля 2017

В некоторых ответах я увидел информацию о пропусках, поэтому решил добавить новую.

Java-коллекции Arrays.asList принимает переменную типа T (T ...). Если вы передадите массив примитивов (массив int), метод asList выведет и сгенерирует List<int[]>, который представляет собой список из одного элемента (один элемент - это массив примитивов). если вы перетасуете этот список из одного элемента, он ничего не изменит.

Итак, сначала вы должны преобразовать свой примитивный массив в массив объектов Wrapper. для этого вы можете использовать ArrayUtils.toObject метод из apache.commons.lang. затем передайте сгенерированный массив в List и, наконец, перемешайте его.

  int[] intArr = {1,2,3};
  List<Integer> integerList = Arrays.asList(ArrayUtils.toObject(array));
  Collections.shuffle(integerList);
  //now! elements in integerList are shuffled!
3 голосов
/ 09 марта 2018

Вот еще один способ перетасовать список

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

Выберите случайное число из исходного списка и сохраните его в другом списке. Затем удалите число из исходного списка. Размер исходного списка будет уменьшаться на единицу, пока все элементы не будут перемещены в новый список.

3 голосов
/ 27 сентября 2016

Вот решение с использованием Apache Commons Math 3.x (только для массивов 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[])

В качестве альтернативы, Apache Commons Lang 3.6 представил новые методы перемешивания для класса ArrayUtils (для объектов и любого примитивного типа).

ArrayUtils.shuffle(array);

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

3 голосов
/ 04 ноября 2014

Вот версия Generics для массивов:

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

Учитывая, что ArrayList - это просто массив, может быть целесообразно работать с ArrayList вместо явного массива и использовать Collections.shuffle (). Тесты производительности, однако, не показывают какой-либо существенной разницы между приведенным выше и 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

Реализация Apache Commons MathArrays.shuffle ограничена int [], и снижение производительности, вероятно, связано с использованием генератора случайных чисел.

3 голосов
/ 15 ноября 2014
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;
}

Кстати, я заметил, что этот код возвращает ar.length - 1 количество элементов, поэтому, если ваш массив имеет 5 элементов, новый перемешанный массив будет иметь 4 элемента. Это происходит потому, что цикл for говорит i>0. Если вы измените на i>=0, все элементы будут перетасованы.

2 голосов
/ 07 декабря 2017

Простое решение для Groovy:

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

Это будет случайным образом сортировать все элементы списка массивов, что архивирует желаемый результат перемешивания всех элементов.

2 голосов
/ 17 февраля 2018
  1. Коробка от int[] до Integer[]
  2. Обтекание массива в список методом Arrays.asList
  3. Перемешать с 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]
    
1 голос
/ 05 июля 2017

Самое простое решение для этой случайной перестановки в массиве.

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 голос
/ 27 октября 2016

Есть и другой способ, пока не публикуйте

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

так проще, зависит от контекста

1 голос
/ 01 июня 2016

Я взвешиваю этот очень популярный вопрос, потому что никто не написал версию в произвольном порядке. Стиль заимствован из Arrays.java, потому что, кто не грабит технологию Java в наши дни? Общие и int реализации включены.

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