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

232

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

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

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

Хьюберт
источник
5
Это метод SDK, который вы ищете для Collections.shuffle (Arrays.asList (array));
Луи Хонг
2
@ Луи Нет, это не работает. Это создаст List<int[]>одну запись. Смотрите мой ответ о том, как добиться этого с помощью Collections.shuffle().
Дункан Джонс
2
Не совсем ответ на первоначальный вопрос, но MathArrays.shuffle из библиотеки commons-math3 делает свою работу.
Сандрис
1
Этого недостаточно для того, чтобы получить ответ, но я помню действительно классную статью из книги «Graphics Gems», в которой говорилось о обходе массива в псевдослучайном порядке. На мой взгляд, это лучше, чем просто перетасовывать данные. C-реализация находится здесь github.com/erich666/GraphicsGems/blob/master/gems/Dissolve.c
Леннарт Роллан
Также смотрите этот тесно связанный вопрос: stackoverflow.com/questions/2450954/…
Pierz

Ответы:

263

Использование коллекций для перемешивания массива примитивных типов - это немного излишне ...

Достаточно просто реализовать эту функцию самостоятельно, например, с помощью перемешивания Фишера-Йейтса :

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;
    }
  }
}
PhiLho
источник
26
Чрезвычайно тривиальный придурок, но вы можете просто использовать println()вместо println(""). Яснее в намерениях я думаю :)
Коуэн
55
Было бы намного лучше использовать Collections.shuffle (Arrays.asList (array)); затем сделать себе перемешать.
Луи Хонг
21
@ Луи Collections.shuffle(Arrays.asList(array))не работает, потому что Arrays.asList(array)возвращается Collection<int[]>не так, Collection<Integer>как вы думали.
Адам Стельмащик
15
@exhuma Потому что, если у вас есть массив тысяч или миллионов примитивных значений для сортировки, оборачивать каждое из них в объект просто для того, чтобы выполнить сортировку, будет немного дорого, как в памяти, так и в процессоре.
Фил
14
Это не случайность Фишера-Йейтса. Это называется дурстенфельдский шаффл . Оригинальный тасовщик Фишер-Йейтса выполняется за время O (n ^ 2), что очень медленно.
Pacerier
164

Вот простой способ использования ArrayList:

List<Integer> solution = new ArrayList<>();
for (int i = 1; i <= 6; i++) {
    solution.add(i);
}
Collections.shuffle(solution);
methodin
источник
1
Вы можете простоCollectons.shuffle(Arrays.asList(solutionArray));
FindOutIslamNow
@ Тиммос Ты не прав. Arrays.asList оборачивает исходный массив и, таким образом, изменяя его, изменяет исходный массив. Вот почему вы не можете добавлять или удалять, потому что массивы имеют фиксированный размер.
Nand
@ Не знаю, о чем я думал, но, глядя на исходный код, действительно, метод Arrays.asList создает ArrayList, поддерживаемый данным массивом. Спасибо за указание на это. Удален мой предыдущий комментарий (не могу его отредактировать).
Тиммос
100

Вот работающая и эффективная функция массива Фишера-Йейтса:

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

или

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
Проголосовал, потому что мне нужно было решение, которое не требовало больших затрат на создание коллекции
целых чисел
2
Разве вторая реализация не может заменить свой собственный индекс? random.nextInt(int bound)является эксклюзивным, но предоставление его i + 1в качестве аргумента позволит indexи iпотенциально может быть таким же.
bmcentee148
21
@ bmcentee148 Обмен элемента с самим собой допустим в случайном порядке. Непонимание этого ослабило Энигму и помогло Алану Тьюрингу взломать ее. en.wikipedia.org/wiki/…
Эллен Спертус
4
xorТрюк отлично подходит для замены регистров процессора , когда процессор не имеют инструкций подкачки и нет свободных регистров, но для замены элементов массива внутри цикла, я не вижу никакой пользы. Для временных локальных переменных нет причин объявлять их вне цикла.
Хольгер
1
Немного эффективнее объявить tempпеременную вне цикла. XORТрюк должен быть быстрее , чем при использовании tempпеременной , но единственный способ быть уверенным , что для выполнения теста бенчмарк.
Дэн Брей
25

Класс Collections имеет эффективный метод тасования, который можно скопировать, чтобы не зависеть от него:

/**
 * 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;
    }
}
Кит-Кат
источник
чтобы не зависеть от этого ? Я бы предпочел зависеть от этого, если бы это было возможно.
shmosel
@shmosel Тогда не стесняйтесь использовать его. Убедитесь, что вы импортировали требуемый класс и преобразовали массив в список с помощью Arrays.asList. Вы должны преобразовать полученный список в массив, тоже
KitKat
Вы не можете использовать Arrays.asList()примитивный массив. И вам не нужно конвертировать его обратно, потому что это просто оболочка.
Шмосель
13

Посмотрите на Collectionsкласс, в частности shuffle(...).

Дейв
источник
8
Как вы используете этот класс коллекций в Android? Вам нужно сделать специальный импорт (CRTL SHIFT O не работает), чтобы использовать его?
Юбер
@ Хьюберт, это должно быть частью пакета java.util. Это часть стандартной библиотеки начиная с версии 1.2.
MauganRa
3
Чтобы сделать ваш ответ более автономным, он должен содержать пример кода. IE:import java.util.Collections; shuffle(solutionArray);
Stevoisiak
10

Вот полное решение с использованием 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);
  }    
}

Обратите внимание, что он страдает из-за неспособности Java плавно переводить между int[]и Integer[](и, следовательно, int[]и List<Integer>).

Дункан Джонс
источник
10

У вас есть несколько вариантов здесь. Список немного отличается от массива, когда дело доходит до перемешивания.

Как вы можете видеть ниже, массив быстрее, чем список, а примитивный массив быстрее, чем массив объектов.

Длительность образца

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

Ниже представлены три различных варианта воспроизведения в случайном порядке. Вы должны использовать Collections.shuffle, только если вы имеете дело с коллекцией. Нет необходимости заключать ваш массив в коллекцию только для его сортировки. Методы ниже очень просты в реализации.

ShuffleUtil Class

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

Полезные методы

Простые служебные методы для копирования и преобразования массивов в списки и наоборот.

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

Range Class

Создает диапазон значений, аналогичный rangeфункции 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
Вы не синхронизируете одни и те же вещи, и вы синхронизируете каждое из них только один раз (тогда их порядок считается, и вы забываете оптимизацию времени выполнения). Вы должны вызывать range, toArrayи toPrimitiveперед любым таймингом, и цикл, чтобы иметь возможность что-либо завершить (псевдокод: сделать несколько раз {генерировать список, arr и iarr; список перетасовки времени; arr перетасовки времени; перестановку времени iarr}). Мои результаты: 1 - й: list: 36017ns, arr: 28262ns, iarr: 23334ns. Сотый: list: 18445ns, arr: 19995ns, iarr: 18657ns. Это просто показывает, что int [] предварительно оптимизирован (по коду), но они почти эквивалентны оптимизации времени выполнения.
Syme
9

Использование ArrayList<Integer>может помочь вам решить проблему перетасовки, не применяя много логики и не тратя меньше времени. Вот что я предлагаю:

ArrayList<Integer> x = new ArrayList<Integer>();
for(int i=1; i<=add.length(); i++)
{
    x.add(i);
}
Collections.shuffle(x);
SalmaanKhan
источник
Вероятно, не последний - занимает меньше времени . На самом деле это, конечно, медленнее, чем примитивные реализации выше.
Борис Паук
1
Для того, чтобы кто-то скопировал код, следите за «циклом», я = 1, может быть, вам нужен я = 0
Борис Карлофф,
5

Вы можете использовать Java 8 сейчас:

Collections.addAll(list, arr);
Collections.shuffle(list);
cardsList.toArray(arr);
Иван Николайчук
источник
2
В этом коде нет ничего специфичного для Java8. Это работает с Java2. Ну, это будет работать, как только вы исправите несоответствие между первым использованием listи внезапным обращением к cardsList. Но так как вам нужно создать временный файл list, который вы пропустили, нет никакого преимущества по сравнению с Collections.shuffle(Arrays.asList(arr));подходом, показанным здесь несколько раз. Который также работает с Java2.
Хольгер
3

Вот версия 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 [], и снижение производительности, вероятно, связано с использованием генератора случайных чисел.

user1050755
источник
1
Похоже, вы можете перейти new JDKRandomGenerator()к MathArrays.shuffle. Интересно, как это влияет на производительность?
Брэндон
На самом деле ... похоже MathArrays#shuffleимеет распределение в своей основной петле: int targetIdx = new UniformIntegerDistribution(rng, start, i).sample();. Bizarre.
Брэндон
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;
}

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

Кристиане Дос Сантос Коста
источник
Просто наперед, вы можете переместить это в раздел комментариев вашего вопроса, так как он, вероятно, будет помечен, если будет оставлен как собственный ответ.
Джейсон Д
1
Это, кажется, отвечает на вопрос, поэтому я не уверен, о чем вы говорите @JasonD
Sumurai8
1
Код правильный, комментарий неправильный. Если вы измените i>0на i>=0, вы тратите время, меняя элемент 0с собой.
jcsahnwaldt восстановить Монику
3

Вот решение с использованием 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

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

Java коллекции Arrays.asList занимает VAR-ARG типа 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!
Mr.Q
источник
3

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

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

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

ПС5
источник
2

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

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

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

Ханс Кристиан
источник
2

Используя Guava Ints.asList()это так же просто, как:

Collections.shuffle(Ints.asList(array));
BeeOnRope
источник
1

Я взвешиваю этот очень популярный вопрос, потому что никто не написал версию в случайном порядке. Стиль сильно заимствован 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;
   }
QED
источник
1

Это алгоритм 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]);
    }
}
BufBills
источник
1

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

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

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

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]);
}
Archit Goel
источник
1
  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]
YujiSoftware
источник
1

Простейший код для перемешивания:

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

Использование случайного класса

  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);
    }
}
}
Нихил Гупта
источник
Пожалуйста, добавьте описание, связанное с вашим ответом.
Анкит Сутар
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

похоже без использования свопа б

        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);
digitebs
источник
0

Одним из решений является использование перестановки для предварительного вычисления всех перестановок и сохранения в ArrayList

Java 8 представила новый метод, ints (), в классе java.util.Random. Метод ints () возвращает неограниченный поток псевдослучайных значений int. Вы можете ограничить случайные числа между указанным диапазоном, указав минимальное и максимальное значения.

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

С помощью генерации случайного числа, вы можете перебрать цикл и поменять местами текущий индекс со случайным числом. Вот так вы можете сгенерировать случайное число с O (1) пространственной сложностью.


источник
0

Без случайного решения:

   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));
    }
izum286
источник