В java, каков наилучший способ установить каждое значение в int [] случайным образом без дубликатов? [Дубликат]

  выберите имя, значение из (выберите имя, значение, ROW_NUMBER () OVER (PARTITION BY name ORDER BY значение desc) как rn из out_pumptable) как a где rn = 1  
26
задан Eric Leschinski 18 September 2013 в 21:32
поделиться

8 ответов

Integer[] arr = {...};
Collections.shuffle(Arrays.asList(arr));

Например:

public static void main(String[] args) {
    Integer[] arr = new Integer[1000];
    for (int i = 0; i < arr.length; i++) {
        arr[i] = i;
    }
    Collections.shuffle(Arrays.asList(arr));
    System.out.println(Arrays.toString(arr));

}
36
ответ дан Achintya Jha 15 August 2018 в 19:54
поделиться
  • 1
    Shuffle отлично, но сначала вы должны создать массив, содержащий числа от 0 до 9999, а затем перетасовать его. Кроме того, какова временная сложность тасования? – Martinsos 14 April 2013 в 15:37
  • 2
    @Martinsos Я создал массив и перетасовал его. Я не уверен, но я думаю, что временная сложность тасования должна быть O (n). Потому что, если вы просто меняете случайным образом внутри массива. – Achintya Jha 14 April 2013 в 16:09

Ачинтья Джа имеет правильную идею здесь. Вместо того, чтобы думать о том, как удалять дубликаты, вы удаляете возможность создания дубликатов в первую очередь.

Если вы хотите придерживаться массива int и хотите рандомизировать их порядок (вручную, который довольно просто) выполните следующие шаги.

  1. создать массив размера n.
  2. пропустить и инициализировать каждое значение с индексом i до значения i (или i + 1, если вы хотите, чтобы числа от 1 до n, а не от 0 до n-1).
  3. , наконец, перебираем массив, снова заменяя каждое значение для значения со случайным индексом.

Ваш код может быть изменен так, чтобы выглядеть так:

import java.util.Random;

public class Sort
{
    // use a constant rather than having the "magic number" 10000 scattered about
    public static final int N = 10000;

    public static void main(String[] args)
    {
        //array to store N random integers (0 - N-1)
        int[] nums = new int[N];

        // initialize each value at index i to the value i 
        for (int i = 0; i < nums.length; ++i)
        {
            nums[i] = i;
        }

        Random randomGenerator = new Random();
        int randomIndex; // the randomly selected index each time through the loop
        int randomValue; // the value at nums[randomIndex] each time through the loop

        // randomize order of values
        for(int i = 0; i < nums.length; ++i)
        {
             // select a random index
             randomIndex = randomGenerator.nextInt(nums.length);

             // swap values
             randomValue = nums[randomIndex];
             nums[randomIndex] = nums[i];
             nums[i] = randomValue;
        }
    }
}

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

Надеюсь, это поможет.

3
ответ дан Benjamin Brumfield 15 August 2018 в 19:54
поделиться
public class Randoms {

static int z, a = 1111, b = 9999, r;

public static void main(String ... args[])
{
       rand();
}

    public static void rand() {

    Random ran = new Random();
    for (int i = 1; i == 1; i++) {
        z = ran.nextInt(b - a + 1) + a;
        System.out.println(z);
        randcheck();
    }
}

private static void randcheck() {

    for (int i = 3; i >= 0; i--) {
        if (z != 0) {
            r = z % 10;
            arr[i] = r;
            z = z / 10;
        }
    }
    for (int i = 0; i <= 3; i++) {
        for (int j = i + 1; j <= 3; j++) {
            if (arr[i] == arr[j]) {
                rand();
            }
        }

    }
}
}
0
ответ дан Jaap 15 August 2018 в 19:54
поделиться

Как насчет этого?

LinkedHashSet<Integer> test = new LinkedHashSet<Integer>();
Random random = new Random();
do{
    test.add(random.nextInt(1000) + 1);
}while(test.size() != 1000);

Затем пользователь может выполнить итерацию через Set с помощью цикла for.

1
ответ дан Jitin Kodian 15 August 2018 в 19:54
поделиться

В Java 8, если вы хотите иметь list не повторяющихся N случайных чисел в range (a, b), где b является исключительным, вы можете использовать что-то вроде этого:

Random random = new Random();
List<Integer> randomNumbers = random.ints(a, b).distinct().limit(N).boxed().collect(Collectors.toList());
1
ответ дан rollstuhlfahrer 15 August 2018 в 19:54
поделиться

Простой алгоритм, который дает вам случайные числа без дубликатов, можно найти в книге Programming Pearls p. 127.

Внимание: результирующий массив содержит числа в порядке! Если вы хотите их в произвольном порядке, вы должны перетасовать массив, либо с помощью Fisher-Yates shuffle , либо с помощью списка и вызова Collections.shuffle().

Преимущество этого алгоритм заключается в том, что вам не нужно создавать массив со всеми возможными числами, а сложность выполнения по-прежнему линейна O(n).

public static int[] sampleRandomNumbersWithoutRepetition(int start, int end, int count) {
    Random rng = new Random();

    int[] result = new int[count];
    int cur = 0;
    int remaining = end - start;
    for (int i = start; i < end && count > 0; i++) {
        double probability = rng.nextDouble();
        if (probability < ((double) count) / (double) remaining) {
            count--;
            result[cur++] = i;
        }
        remaining--;
    }
    return result;
}
7
ответ дан the 15 August 2018 в 19:54
поделиться
  • 1
    Примечание: (re: ваш раздел «Внимание») Collections.shuffle выполняет перетасовку Fisher-Yates, поэтому он не является «или« или », ситуация. – Erwin Bolwidt 6 December 2017 в 05:01
  • 2
    Вы правы, Collections.shuffle перетасовывает Fisher-Yates, но вам нужно использовать List. Arrays.asList требуется, чтобы массив имел тип Integer вместо int для правильного преобразования, тогда вам не нужно выделять дополнительную память. Написание перетасовки Fisher-Yates позволяет избежать преобразования и дополнительной памяти не требуется. – the 7 December 2017 в 12:34
  • 3
    просто пытаясь понять, почему probability < ((double) count) / (double) remaining необходим? почему бы не заполнить массив от начала до конца и просто перетасовать? – brain storm 20 July 2018 в 03:26

Если вам нужно сгенерировать числа с интервалами, это может быть так:

Integer[] arr = new Integer[((int) (Math.random() * (16 - 30) + 30))];
for (int i = 0; i < arr.length; i++) {
arr[i] = i;
}
Collections.shuffle(Arrays.asList(arr));
System.out.println(Arrays.toString(arr));`

Результат:

[1, 10, 2, 4, 9, 8, 7, 13, 18, 17, 5, 21, 12, 16, 23, 20, 6, 0, 22, 14, 24, 15, 3, 11, 19]

Примечание:

Если вам нужно, чтобы ноль не покидал вас, вы могли бы поставить «if»

2
ответ дан user3760016 15 August 2018 в 19:54
поделиться
0
ответ дан Ori Dar 29 October 2018 в 03:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: