Создание уникальных случайных чисел в Java

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

Random rand = new Random();
selected = rand.nextInt(100);

Ответ 1

  • Добавьте каждое число в диапазон последовательно в структуре list.
  • Shuffle it.
  • Возьмите первый "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 засевается текущим временем в миллисекундах. Для определенного начального значения случайный экземпляр вернет ту же самую последовательность псевдослучайных чисел.

Ответ 2

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

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

Random также имеет методы, которые создают LongStream и DoubleStream, если вам это нужно.

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

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

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

Ответ 4

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

Ответ 5

Мне кажется, что этот метод стоит упомянуть.

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

Ответ 6

Я повторно проанализировал ответ Anand, чтобы использовать не только уникальные свойства Set, но также использовать логическое 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);
    }
}

Ответ 7

Я сделал это так.

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

Ответ 8

Это будет работать для генерации уникальных случайных чисел................

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

Ответ 9

Я пришел сюда из другого вопроса, который был дубликат этого вопроса (Создание уникального случайного числа в java)

  • Хранить от 1 до 100 номеров в массиве.

  • Создайте случайное число от 1 до 100 в качестве позиции и возвращаемого массива [позиция-1], чтобы получить значение

  • Как только вы используете число в массиве, отметьте значение как -1 (нет необходимости поддерживать другой массив, чтобы проверить, используется ли этот номер)

  • Если значение в массиве равно -1, снова получите случайное число, чтобы получить новое местоположение в массиве.

Ответ 10

Один разумный способ сделать это - использовать экспоненты примитивного элемента в модуле.

Например, 2 является примитивным корнем mod 101, что означает, что степени 2 mod 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;
    }
}

Поиск примитивного корня для конкретного модуля может быть сложным, но функция Maple "primroot" сделает это для вас.

Ответ 11

попробуйте это

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

Ответ 12

Это не сильно отличается от других ответов, но в конце я хотел получить массив целых чисел:

    Integer[] indices = new Integer[n];
    Arrays.setAll(indices, i -> i);
    Collections.shuffle(Arrays.asList(indices));
    return Arrays.stream(indices).mapToInt(Integer::intValue).toArray();

Ответ 13

Ниже приведен способ, которым я всегда использовал уникальный номер. Случайная функция генерирует число и сохраняет его в текстовом файле, а затем в следующий раз, когда он проверяет его в файле, сравнивает его и генерирует новый уникальный номер, следовательно, всегда есть новый уникальный номер.

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;

}

Ответ 14

вы можете использовать логический массив, чтобы заполнить значение true, если значение принятое еще задано, перемещаться по булевскому массиву, чтобы получить значение согласно приведенному ниже

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

    }

}

Ответ 15

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

for(int i=0;i<4;i++)
        {
            rn[i]= GenerateRandomNumber();
            for (int j=0;j<i;j++)
            {
                if (rn[i] == rn[j])
                {
                    i--;
                }
            }
        }

Ответ 16

Выберите 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. Сделайте еще один вывод, вы можете получить этот алгоритм.

Ответ 17

Проверьте это

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