Випадкове переміщення масиву


232

Мені потрібно випадково перетасувати наступний масив:

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

Чи є якась функція для цього?


5
Це метод SDK, який ви шукаєте Collections.shuffle (Arrays.asList (масив));
Луї Гонг

2
@Louie Ні, це не працює. Це створило б List<int[]>один запис. Дивіться мою відповідь про спосіб досягнення цього за допомогою Collections.shuffle().
Дункан Джонс

2
Насправді не відповідь на початкове запитання, але MathArrays.shuffle з бібліотеки commons-math3 виконує цю роботу.
сандріс

1
Це недостатньо тематично, щоб надати відповідь, але я пам’ятаю дійсно класну статтю з книги «Графічні дорогоцінні камені», яка розповідала про проходження масиву в псевдо випадковому порядку. На мій погляд, б'є, що насправді потрібно перетасувати дані в першу чергу. C-реалізацію можна знайти тут github.com/erich666/GraphicsGems/blob/master/gems/Dissolve.c
Lennart Rolland

Також дивіться це тісно пов’язане питання: stackoverflow.com/questions/2450954/…
Pierz

Відповіді:


263

Використання колекцій для перетасування масиву примітивних типів - це трохи зайве ...

Досить просто реалізувати функцію самостійно, використовуючи, наприклад, переміщення 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
Надзвичайно банальний нітпік, але його можна просто використовувати println()замість println(""). Ясніше в намірі, я думаю :)
Cowan,

55
Було б набагато краще використовувати Collections.shuffle (Arrays.asList (масив)); то роблячи перемішання себе.
Луї Гонг

21
@Louie Collections.shuffle(Arrays.asList(array))не працює, тому що Arrays.asList(array)повертається Collection<int[]>не так, Collection<Integer>як ви думали.
Адам Стельмащик

15
@exhuma Оскільки, якщо у вас є масив тисяч чи мільйонів примітивних значень для сортування, загортання кожного в об’єкт просто для сортування - це трохи дорого, як у пам'яті, так і в процесорі.
PhiLho

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

1
Можна простоCollectons.shuffle(Arrays.asList(solutionArray));
FindOutIslamNow

@Timmos Ви помиляєтесь. Arrays.asList обертається навколо вихідного масиву і таким чином модифікуючи його, змінює вихідний масив. Ось чому ви не можете додавати або видаляти, оскільки масиви мають фіксований розмір.
Нанд

@Я не впевнений, про що я думав, але дивлячись на вихідний код, дійсно метод Arrays.asList створює ArrayList, підкріплений даним масивом. Дякуємо, що вказали на це. Мій попередній коментар видалено (редагувати його не вдалося).
Тіммос

100

Ось працююча та ефективна функція масиву перетасовки 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];
        }
    }
}

або

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
Голосували, тому що мені було потрібне рішення, яке не мало великих витрат на створення колекції цілочисел
mwk

2
Хіба друга імплементація не має потенціалу замінятися власним індексом? random.nextInt(int bound)є ексклюзивним, але подання його i + 1в якості аргументу дозволило б indexі, iможливо, те саме.
bmcentee148

21
@ bmcentee148 Заміна елемента на себе допустима у випадковому впорядкуванні. Не розуміючи цього, послабило Енігму і допомогло Алану Тьюрінгу розбити її. en.wikipedia.org/wiki/…
Еллен Спертус

4
xorТрюк відмінно підходить для заміни регістрів процесора , коли процесор не мають інструкцій підкачки і немає вільних регістрів, але для заміни елементів масиву всередині циклу, я не бачу ніякої користі. Для тимчасових локальних змінних немає причин оголошувати їх поза циклом.
Холгер

1
Дещо ефективніше оголосити tempзмінну за межами циклу. XORТрюк повинен бути швидше , ніж при використанні tempзмінної , але єдиний спосіб бути впевненим , що для виконання тесту бенчмарк.
Ден Брей

25

Клас колекцій має ефективний метод перетасування, який можна скопіювати, щоб не залежати від нього:

/**
 * 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 не працює)?
Хуберт

@Hubert це має бути частиною пакету 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);
  }    
}

Зверніть увагу , що він страждає - нездатність Яви плавно переводити між int[]і Integer[](і , таким чином , int[]і List<Integer>).


10

Тут у вас є пара варіантів. Список дещо відрізняється від масиву, коли мова йде про переміщення.

Як ви бачите нижче, масив швидший за список, а примітивний масив - швидше, ніж об’єктний масив.

Зразок тривалості

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

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

Клас 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;

Основний метод

    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функції 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; список перетасовки часу; time shuffling arr; time shuffling 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);

Напевно, не остання - витрачає менше часу . Насправді це, безумовно, повільніше, ніж примітивні реалізації вище.
Борис Павук

1
Хтось копіює код, дивіться "для циклу" i = 1, можливо, вам знадобиться i = 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 [], а покарання за продуктивність, ймовірно, пов'язане з використовуваним генератором випадкових чисел.


1
Схоже , що ви можете перейти new JDKRandomGenerator()до MathArrays.shuffle. Цікаво, як це впливає на продуктивність?
Брендон

На насправді ... схоже MathArrays#shuffleмає розподіл у своїй основній петлі: int targetIdx = new UniformIntegerDistribution(rng, start, i).sample();. Химерність.
Брендон

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 зробить висновок і згенерує aList<int[]> , що є одним списком елементів (один елемент - примітивний масив). якщо перетасувати цей список одного елемента, він нічого не змінить.

Отже, спочатку вам доведеться перетворити ваш примітивний масив в об’єктний масив Wrapper. для цього ви можете використовувати ArrayUtils.toObjectметод з apache.commons.lang. потім передайте згенерований масив до списку та остаточно перетасуйте це.

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

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

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


2

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

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

Це дозволить сортувати всі елементи списку масивів випадковим чином, які архівують потрібний результат переміщення всіх елементів.



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

1

Це алгоритм переміщення по кнуту.

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

Є ще один спосіб - ще не дописувати

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

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]

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

Будь ласка, додайте відповідне опис щодо вашої відповіді.
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

подібні без використання 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

Одним з рішень є використання перестановки для попереднього обчислення всіх перестановок і збережених у 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));
    }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.