Вопрос-ответ

Generating Unique Random Numbers in Java

Генерация уникальных случайных чисел в Java

Я пытаюсь получить случайные числа от 0 до 100. Но я хочу, чтобы они были уникальными, а не повторялись в последовательности. Например, если я получил 5 чисел, они должны быть 82,12,53,64,32, а не 82,12,53,12,32. Я использовал это, но оно генерирует одинаковые числа в последовательности.

Random rand = new Random();
selected = rand.nextInt(100);
Переведено автоматически
Ответ 1

  • Добавляйте каждое число в диапазоне последовательно в структуру списка.

  • Перетасуйте это.

  • Возьмите первое 'n'.

Вот простая реализация. При этом будут выведены 3 уникальных случайных числа из диапазона 1-10.

import java.util.ArrayList;
import java.util.Collections;

public class UniqueRandomNumbers {

public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i=1; i<11; i++) list.add(i);
Collections.shuffle(list);
for (int i=0; i<3; i++) System.out.println(list.get(i));
}
}

Первая часть исправления при оригинальном подходе, как указал Марк Байерс в ответе, который теперь удален, заключается в использовании только одного Random экземпляра.

Именно это приводит к тому, что числа становятся идентичными. A Random экземпляр заполняется текущим временем в миллисекундах. Для определенного начального значения экземпляр 'random' вернет точно такую же последовательность псевдослучайных чисел.

Ответ 2

В Java 8+ вы можете использовать ints метод Random, чтобы получить IntStream количество случайных значений, затем distinct и limit сократить поток до количества уникальных случайных значений.

ThreadLocalRandom.current().ints(0, 100).distinct().limit(5).forEach(System.out::println);

Random также есть методы, которые создают LongStreams и DoubleStreams, если они вам нужны вместо этого.

Если вам нужны все (или большое количество) чисел в диапазоне в случайном порядке, возможно, было бы эффективнее добавить все числа в список, перетасовать его и взять первое n, потому что приведенный выше пример в настоящее время реализован путем генерации случайных чисел в запрошенном диапазоне и передачи их через набор (аналогично ответу Роба Кьелти), что может потребовать генерации намного большего количества, чем количество, переданное в limit, поскольку вероятность генерации нового уникального числа уменьшается с каждым найденным. Вот пример другого способа:

List<Integer> range = IntStream.range(0, 100).boxed()
.collect(Collectors.toCollection(ArrayList::new));
Collections.shuffle(range);
range.subList(0, 99).forEach(System.out::println);
Ответ 3

  1. Создайте массив из 100 чисел, затем рандомизируйте их порядок.

  2. Разработайте генератор псевдослучайных чисел с диапазоном 100.

  3. Создайте логический массив из 100 элементов, затем установите значение элемента true при выборе этого числа. При выборе следующего числа сверьтесь с массивом и попробуйте снова, установлен ли элемент массива. (Вы можете создать простой в очистке логический массив с массивом long, куда вы сдвигаете и маскируете для доступа к отдельным битам.)

Ответ 4

Используйте Collections.shuffle() для всех 100 чисел и выберите первые пять, как показано здесь и ниже.

Консоль:

59 9 68 24 82

Код:

private static final Random rnd = new Random();
private static final int N = 100;
private static final int K = 5;
private static final List<Integer> S = new ArrayList<>(N);

public static void main(String[] args) {
for (int i = 0; i < N; i++) {
S.add(i + 1);
}
Collections.shuffle(S, rnd);
for (int i = 0; i < K; i++) {
System.out.print(S.get(i) + " ");
}
System.out.println();
}
java