Я пытаюсь получить случайные числа от 0 до 100. Но я хочу, чтобы они были уникальными, а не повторялись в последовательности. Например, если у меня 5 чисел, они должны быть 82,12,53,64,32, а не 82,12,53,12,32. Я использовал это, но он генерирует одинаковые числа в последовательности.
Random rand = new Random();
selected = rand.nextInt(100);
1..100
(для этого есть известные алгоритмы), но остановитесь после определения первых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(new Integer(i)); } Collections.shuffle(list); for (int i=0; i<3; i++) { System.out.println(list.get(i)); } } }
Первая часть исправления с исходным подходом, как указал Марк Байерс в ответе, который теперь удален, заключается в использовании только одного
Random
экземпляра.Вот почему числа совпадают.
Random
Экземпляр высевают на текущий момент времени в миллисекундах. Для определенного начального значения «случайный» экземпляр вернет точно такую же последовательность псевдослучайных чисел.Первый цикл for можно просто изменить на:
for (int i = 1; i < 11; i++) { list.add(i); }
источник
В Java 8+ вы можете использовать
ints
метод,Random
чтобы затем получитьIntStream
случайные значенияdistinct
иlimit
уменьшить поток до числа уникальных случайных значений.ThreadLocalRandom.current().ints(0, 100).distinct().limit(5).forEach(System.out::println);
Random
также есть методы, которые создаютLongStream
s иDoubleStream
s, если они вам нужны.Если вы хотите, чтобы все (или большое количество) чисел в диапазоне были в случайном порядке, может быть более эффективным добавить все числа в список, перемешать его и взять первое n, потому что приведенный выше пример в настоящее время реализован путем генерации случайных чисел в запрошенном диапазоне и передачи их через набор (аналогично ответу Роба Килти ), что может потребовать генерации намного большего количества, чем переданное для ограничения, поскольку вероятность создания нового уникального числа уменьшается с каждым найденным. Вот пример другого пути:
List<Integer> range = IntStream.range(0, 100).boxed() .collect(Collectors.toCollection(ArrayList::new)); Collections.shuffle(range); range.subList(0, 99).forEach(System.out::println);
источник
Arrays#setAll()
он немного быстрее, чем поток. Итак: `Integer [] index = new Integer [n]; Arrays.setAll (индексы, i -> i); Collections.shuffle (Arrays.asList (индексы)); return Arrays.stream (индексы) .mapToInt (Integer :: intValue) .toArray (); `long
котором вы сдвигаете и маскируете для доступа к отдельным битам.)источник
pick()
это пример.HashSet
, где вы храните числа, которые вы уже сгенерировали, и используете ихcontains
для проверки, если вы уже сгенерировали это число.HashSet
, Вероятно , будет немного медленнее , чем булева массива, но занимают меньше памяти.Используйте
Collections.shuffle()
все 100 чисел и выберите первые пять, как показано здесь .источник
Мне кажется, об этом методе стоит упомянуть.
private static final Random RANDOM = new Random(); /** * Pick n numbers between 0 (inclusive) and k (inclusive) * While there are very deterministic ways to do this, * for large k and small n, this could be easier than creating * an large array and sorting, i.e. k = 10,000 */ public Set<Integer> pickRandom(int n, int k) { final Set<Integer> picked = new HashSet<>(); while (picked.size() < n) { picked.add(RANDOM.nextInt(k + 1)); } return picked; }
источник
Я повторно факторизовал ответ Ананда, чтобы использовать не только уникальные свойства набора, но также использовать логическое значение false, возвращаемое
set.add()
при сбое добавления в набор.import java.util.HashSet; import java.util.Random; import java.util.Set; public class randomUniqueNumberGenerator { public static final int SET_SIZE_REQUIRED = 10; public static final int NUMBER_RANGE = 100; public static void main(String[] args) { Random random = new Random(); Set set = new HashSet<Integer>(SET_SIZE_REQUIRED); while(set.size()< SET_SIZE_REQUIRED) { while (set.add(random.nextInt(NUMBER_RANGE)) != true) ; } assert set.size() == SET_SIZE_REQUIRED; System.out.println(set); } }
источник
SET_SIZE_REQUIRED
она достаточно велика (скажем, больше, чемNUMBER_RANGE / 2
тогда, у вас гораздо большее ожидаемое время выполнения.Я сделал это вот так.
Random random = new Random(); ArrayList<Integer> arrayList = new ArrayList<Integer>(); while (arrayList.size() < 6) { // how many numbers u need - it will 6 int a = random.nextInt(49)+1; // this will give numbers between 1 and 50. if (!arrayList.contains(a)) { arrayList.add(a); } }
источник
Это будет работать для генерации уникальных случайных чисел ................
import java.util.HashSet; import java.util.Random; public class RandomExample { public static void main(String[] args) { Random rand = new Random(); int e; int i; int g = 10; HashSet<Integer> randomNumbers = new HashSet<Integer>(); for (i = 0; i < g; i++) { e = rand.nextInt(20); randomNumbers.add(e); if (randomNumbers.size() <= 10) { if (randomNumbers.size() == 10) { g = 10; } g++; randomNumbers.add(e); } } System.out.println("Ten Unique random numbers from 1 to 20 are : " + randomNumbers); } }
источник
Один из умных способов сделать это - использовать экспоненты примитивного элемента в модуле.
Например, 2 является примитивным корневым модулем 101, что означает, что степени 2 по модулю 101 дают вам неповторяющуюся последовательность, которая видит каждое число от 1 до 100 включительно:
2^0 mod 101 = 1 2^1 mod 101 = 2 2^2 mod 101 = 4 ... 2^50 mod 101 = 100 2^51 mod 101 = 99 2^52 mod 101 = 97 ... 2^100 mod 101 = 1
В коде Java вы должны написать:
void randInts() { int num=1; for (int ii=0; ii<101; ii++) { System.out.println(num); num= (num*2) % 101; } }
Найти примитивный корень для определенного модуля может быть непросто, но функция "primroot" в Maple сделает это за вас.
источник
Я пришел сюда из другого вопроса, который дублировал этот вопрос ( создание уникального случайного числа в java )
Храните от 1 до 100 чисел в массиве.
Сгенерировать случайное число от 1 до 100 в качестве позиции и вернуть массив [позиция-1], чтобы получить значение
После того, как вы используете число в массиве, отметьте значение как -1 (нет необходимости поддерживать другой массив, чтобы проверить, используется ли это число уже)
Если значение в массиве равно -1, снова получите случайное число, чтобы получить новое местоположение в массиве.
источник
У меня есть простое решение этой проблемы. С его помощью мы можем легко сгенерировать n уникальных случайных чисел. Это простая логика, которую каждый может использовать на любом языке.
for(int i=0;i<4;i++) { rn[i]= GenerateRandomNumber(); for (int j=0;j<i;j++) { if (rn[i] == rn[j]) { i--; } } }
источник
break;
послеi—;
попробуйте это
public class RandomValueGenerator { /** * */ private volatile List<Double> previousGenValues = new ArrayList<Double>(); public void init() { previousGenValues.add(Double.valueOf(0)); } public String getNextValue() { Random random = new Random(); double nextValue=0; while(previousGenValues.contains(Double.valueOf(nextValue))) { nextValue = random.nextDouble(); } previousGenValues.add(Double.valueOf(nextValue)); return String.valueOf(nextValue); } }
источник
Это не сильно отличается от других ответов, но в конце мне нужен массив целых чисел:
Integer[] indices = new Integer[n]; Arrays.setAll(indices, i -> i); Collections.shuffle(Arrays.asList(indices)); return Arrays.stream(indices).mapToInt(Integer::intValue).toArray();
источник
вы можете использовать логический массив, чтобы заполнить истину, если значение взято, иначе установите переход по логическому массиву, чтобы получить значение, как указано ниже
package study; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /* Created By Sachin Rane on Jul 18, 2018 */ public class UniqueRandomNumber { static Boolean[] boolArray; public static void main(String s[]){ List<Integer> integers = new ArrayList<>(); for (int i = 0; i < 10; i++) { integers.add(i); } //get unique random numbers boolArray = new Boolean[integers.size()+1]; Arrays.fill(boolArray, false); for (int i = 0; i < 10; i++) { System.out.print(getUniqueRandomNumber(integers) + " "); } } private static int getUniqueRandomNumber(List<Integer> integers) { int randNum =(int) (Math.random()*integers.size()); if(boolArray[randNum]){ while(boolArray[randNum]){ randNum++; if(randNum>boolArray.length){ randNum=0; } } boolArray[randNum]=true; return randNum; }else { boolArray[randNum]=true; return randNum; } } }
источник
Выберите n уникальных случайных чисел от 0 до m-1.
int[] uniqueRand(int n, int m){ Random rand = new Random(); int[] r = new int[n]; int[] result = new int[n]; for(int i = 0; i < n; i++){ r[i] = rand.nextInt(m-i); result[i] = r[i]; for(int j = i-1; j >= 0; j--){ if(result[i] >= r[j]) result[i]++; } } return result; }
Представьте себе список, содержащий числа от 0 до m-1. Чтобы выбрать первое число, мы просто используем
rand.nextInt(m)
. Затем удалите номер из списка. Теперь осталось m-1 номеров, поэтому звонимrand.nextInt(m-1)
. Число, которое мы получаем, представляет позицию в списке. Если оно меньше первого числа, то это второе число, поскольку часть списка перед первым числом не была изменена удалением первого числа. Если позиция больше или равна первому числу, второе число равно позиции + 1. Сделайте некоторые дальнейшие выводы, вы можете получить этот алгоритм.Объяснение
Этот алгоритм имеет сложность O (n ^ 2). Так что он хорош для создания небольшого количества уникальных чисел из большого набора. В то время как алгоритм на основе перемешивания требует как минимум O (m) для выполнения перемешивания.
Кроме того, алгоритм на основе перемешивания требует памяти для хранения всех возможных результатов для выполнения перемешивания, этот алгоритм не нуждается.
источник
Вы можете использовать класс Collections.
Служебный класс под названием Collections предлагает различные действия, которые могут быть выполнены с коллекцией, например ArrayList (например, поиск элементов, поиск максимального или минимального элемента, изменение порядка элементов и т. Д.). Одно из действий, которое он может выполнить, - это перемешать элементы. В случайном порядке каждый элемент случайным образом перемещается в другую позицию в списке. Это делается с помощью объекта Random. Это означает, что это детерминированная случайность, но так будет в большинстве ситуаций.
Чтобы перемешать ArrayList, добавьте импорт коллекций в начало программы, а затем используйте статический метод Shuffle. В качестве параметра необходимо перетасовать список ArrayList:
import java.util.Collections; import java.util.ArrayList; public class Lottery { public static void main(String[] args) { //define ArrayList to hold Integer objects ArrayList numbers = new ArrayList(); for(int i = 0; i < 100; i++) { numbers.add(i+1); } Collections.shuffle(numbers); System.out.println(numbers); } }
источник
Хотя это старый поток, но добавление другого варианта может не повредить. (Лямбда-функции JDK 1.8, кажется, упрощают эту задачу);
Проблема может быть разбита на следующие шаги;
Вот функция с некоторым описанием:
/** * Provided an unsequenced / sequenced list of integers, the function returns unique random IDs as defined by the parameter * @param numberToGenerate * @param idList * @return List of unique random integer values from the provided list */ private List<Integer> getUniqueRandomInts(List<Integer> idList, Integer numberToGenerate) { List<Integer> generatedUniqueIds = new ArrayList<>(); Integer minId = idList.stream().mapToInt (v->v).min().orElseThrow(NoSuchElementException::new); Integer maxId = idList.stream().mapToInt (v->v).max().orElseThrow(NoSuchElementException::new); ThreadLocalRandom.current().ints(minId,maxId) .filter(e->idList.contains(e)) .distinct() .limit(numberToGenerate) .forEach(generatedUniqueIds:: add); return generatedUniqueIds; }
Итак, чтобы получить 11 уникальных случайных чисел для объекта списка allIntegers, мы вызовем функцию вида:
List<Integer> ids = getUniqueRandomInts(allIntegers,11);
Функция объявляет новый список arrayList «generatedUniqueIds» и заполняет его каждым уникальным случайным целым числом до требуемого числа перед возвратом.
Класс PS ThreadLocalRandom избегает общего начального значения в случае параллельных потоков.
источник
Это самый простой метод генерации уникальных случайных значений в диапазоне или из массива. .
В этом примере я буду использовать предопределенный массив, но вы также можете адаптировать этот метод для генерации случайных чисел. Сначала мы создадим образец массива, из которого будут извлекаться наши данные.
ArrayList<Integer> sampleList = new ArrayList<>(); sampleList.add(1); sampleList.add(2); sampleList.add(3); sampleList.add(4); sampleList.add(5); sampleList.add(6); sampleList.add(7); sampleList.add(8);
Теперь
sampleList
мы получим пять уникальных случайных чисел.int n; randomList = new ArrayList<>(); for(int i=0;i<5;i++){ Random random = new Random(); n=random.nextInt(8); //Generate a random index between 0-7 if(!randomList.contains(sampleList.get(n))) randomList.add(sampleList.get(n)); else i--; //reiterating the step }
Концептуально это очень просто. Если сгенерированное случайное значение уже существует, мы повторим этот шаг. Это будет продолжаться до тех пор, пока все сгенерированные значения не станут уникальными.
Если вы нашли этот ответ полезным, вы можете проголосовать за него, так как он намного проще по концепции по сравнению с другими ответами .
источник
Вы можете сгенерировать n уникальных случайных чисел от 0 до n-1 в java
public static void RandomGenerate(int n) { Set<Integer> st=new HashSet<Integer>(); Random r=new Random(); while(st.size()<n) { st.add(r.nextInt(n)); }
}
источник
Проверь это
public class RandomNumbers { public static void main(String[] args) { // TODO Auto-generated method stub int n = 5; int A[] = uniqueRandomArray(n); for(int i = 0; i<n; i++){ System.out.println(A[i]); } } public static int[] uniqueRandomArray(int n){ int [] A = new int[n]; for(int i = 0; i< A.length; ){ if(i == A.length){ break; } int b = (int)(Math.random() *n) + 1; if(f(A,b) == false){ A[i++] = b; } } return A; } public static boolean f(int[] A, int n){ for(int i=0; i<A.length; i++){ if(A[i] == n){ return true; } } return false; } }
источник
Ниже приведен способ, которым я всегда генерировал уникальный номер. Случайная функция генерирует число и сохраняет его в текстовом файле, а затем в следующий раз, когда она проверяет его в файле, сравнивает его и генерирует новый уникальный номер, следовательно, таким образом всегда есть новый уникальный номер.
public int GenerateRandomNo() { int _min = 0000; int _max = 9999; Random _rdm = new Random(); return _rdm.Next(_min, _max); } public int rand_num() { randnum = GenerateRandomNo(); string createText = randnum.ToString() + Environment.NewLine; string file_path = System.IO.Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + @"\Invoices\numbers.txt"; File.AppendAllText(file_path, createText); int number = File.ReadLines(file_path).Count(); //count number of lines in file System.IO.StreamReader file = new System.IO.StreamReader(file_path); do { randnum = GenerateRandomNo(); } while ((file.ReadLine()) == randnum.ToString()); file.Close(); return randnum; }
источник