Создание случайных чисел без дубликатов - PullRequest
80 голосов
/ 28 октября 2010

В этом случае MAX только 5, так что я могу проверить дубликаты один за другим, но как я могу сделать это проще?Например, что если MAX имеет значение 20?Спасибо.

int MAX = 5;

for (i = 1 , i <= MAX; i++)
{
        drawNum[1] = (int)(Math.random()*MAX)+1;

        while (drawNum[2] == drawNum[1])
        {
             drawNum[2] = (int)(Math.random()*MAX)+1;
        }
        while ((drawNum[3] == drawNum[1]) || (drawNum[3] == drawNum[2]) )
        {
             drawNum[3] = (int)(Math.random()*MAX)+1;
        }
        while ((drawNum[4] == drawNum[1]) || (drawNum[4] == drawNum[2]) || (drawNum[4] == drawNum[3]) )
        {
             drawNum[4] = (int)(Math.random()*MAX)+1;
        }
        while ((drawNum[5] == drawNum[1]) ||
               (drawNum[5] == drawNum[2]) ||
               (drawNum[5] == drawNum[3]) ||
               (drawNum[5] == drawNum[4]) )
        {
             drawNum[5] = (int)(Math.random()*MAX)+1;
        }

}

Ответы [ 16 ]

2 голосов
/ 28 октября 2010

Вы можете использовать один из классов, реализующих интерфейс Set ( API ), а затем каждое сгенерированное вами число использовать Set.add () для его вставки.

Если возвращаемое значение равно false, вы знаете, что число уже было сгенерировано ранее.

0 голосов
/ 05 апреля 2019

Следующий код создает случайное число последовательности между [1, m], которое не было сгенерировано ранее.

public class NewClass {

    public List<Integer> keys = new ArrayList<Integer>();

    public int rand(int m) {
        int n = (int) (Math.random() * m + 1);
        if (!keys.contains(n)) {
            keys.add(n);
            return n;
        } else {
            return rand(m);
        }
    }

    public static void main(String[] args) {
        int m = 4;
        NewClass ne = new NewClass();
        for (int i = 0; i < 4; i++) {
            System.out.println(ne.rand(m));
        }
        System.out.println("list: " + ne.keys);
    }
}
0 голосов
/ 19 декабря 2013

На самом деле все зависит от того, ЧТО именно вам нужно для генерации случайных чисел, но вот мое мнение.

Во-первых, создайте автономный метод для генерации случайного числа.Обязательно учитывайте ограничения.

public static int newRandom(int limit){
    return generatedRandom.nextInt(limit);  }

Далее вам нужно будет создать очень простую структуру принятия решений, которая сравнивает значения.Это можно сделать одним из двух способов.Если у вас есть очень ограниченное количество чисел для проверки, достаточно простого оператора IF:

public static int testDuplicates(int int1, int int2, int int3, int int4, int int5){
    boolean loopFlag = true;
    while(loopFlag == true){
        if(int1 == int2 || int1 == int3 || int1 == int4 || int1 == int5 || int1 == 0){
            int1 = newRandom(75);
            loopFlag = true;    }
        else{
            loopFlag = false;   }}
    return int1;    }

Приведенное выше сравнение сравнивает int1 с int2 через int5, а также проверяет отсутствие нулей в рандомах.

Используя эти два метода, мы можем сделать следующее:

    num1 = newRandom(limit1);
    num2 = newRandom(limit1);
    num3 = newRandom(limit1);
    num4 = newRandom(limit1);
    num5 = newRandom(limit1);

Далее:

        num1 = testDuplicates(num1, num2, num3, num4, num5);
        num2 = testDuplicates(num2, num1, num3, num4, num5);
        num3 = testDuplicates(num3, num1, num2, num4, num5);
        num4 = testDuplicates(num4, num1, num2, num3, num5);
        num5 = testDuplicates(num5, num1, num2, num3, num5);

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

Надеюсь, это поможет.Этот сайт очень помог мне, и я чувствовал себя обязанным хотя бы попытаться помочь.

0 голосов
/ 01 августа 2012

Существует более эффективное и менее громоздкое решение для целых чисел, чем Collections.shuffle.

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

Этот алгоритм работает для загрузки любого массива и достижения случайного порядка в конце загрузки.Он также работает для добавления в коллекцию List (или любую другую проиндексированную коллекцию) и получения случайной последовательности в коллекции в конце добавления.

Это можно сделать с помощью одного массива, созданного один раз, или с помощью упорядоченного по нумерации набора, такого как список, на месте.Для массива начальный размер массива должен быть точным размером, чтобы содержать все предполагаемые значения.Если вы не знаете, сколько значений может встречаться заранее, сработает также упорядоченная по нумерации коллекция, такая как ArrayList или List, где размер не является неизменяемым.Он будет работать универсально для массива любого размера вплоть до Integer.MAX_VALUE, который составляет чуть более 2 000 000 000.Объекты списка будут иметь одинаковые пределы индекса.Ваша машина может исчерпать память, прежде чем вы получите массив такого размера.Может быть более эффективно загрузить массив, типизированный для типов объектов, и преобразовать его в некоторую коллекцию после загрузки массива.Это особенно верно, если целевая коллекция не численно проиндексирована.

Этот алгоритм, в точности как написано, создаст очень равномерное распределение, где нет дубликатов.Один аспект, который ОЧЕНЬ ВАЖЕН, заключается в том, что должна быть возможность вставки следующего элемента до текущего размера +1. Таким образом, для второго элемента может быть возможно сохранить его в местоположении 0 или местоположении 1Для 20-го предмета можно было бы сохранить его в любом месте, от 0 до 19. Это также возможно, как первый предмет, который останется в месте 0, так как он может оказаться в любом другом месте.Вполне возможно, что следующий новый элемент может попасть куда угодно, включая следующее новое местоположение.

Случайность последовательности будет такой же случайной, как и случайность генератора случайных чисел.

Этот алгоритм также может использоваться для загрузки ссылочных типов в случайные места в массиве.Поскольку это работает с массивом, оно также может работать с коллекциями.Это означает, что вам не нужно создавать коллекцию, а затем перетасовывать ее или упорядочивать по порядку вставляемых объектов.Коллекции нужно только иметь возможность вставить элемент в любую точку коллекции или добавить его.

// RandomSequence.java
import java.util.Random;
public class RandomSequence {

    public static void main(String[] args) {
        // create an array of the size and type for which
        // you want a random sequence
        int[] randomSequence = new int[20];
        Random randomNumbers = new Random();

        for (int i = 0; i < randomSequence.length; i++ ) {
            if (i == 0) { // seed first entry in array with item 0
                randomSequence[i] = 0; 
            } else { // for all other items...
                // choose a random pointer to the segment of the
                // array already containing items
                int pointer = randomNumbers.nextInt(i + 1);
                randomSequence[i] = randomSequence[pointer]; 
                randomSequence[pointer] = i;
                // note that if pointer & i are equal
                // the new value will just go into location i and possibly stay there
                // this is VERY IMPORTANT to ensure the sequence is really random
                // and not biased
            } // end if...else
        } // end for
        for (int number: randomSequence) {
                System.out.printf("%2d ", number);
        } // end for
    } // end main
} // end class RandomSequence
0 голосов
/ 28 октября 2010

Здесь - эффективное решение для быстрого создания рандомизированного массива. После рандомизации вы можете просто выбрать n -й элемент e массива, увеличить n и вернуть e. Это решение имеет O (1) для получения случайного числа и O (n) для инициализации, но в качестве компромисса требуется хороший объем памяти, если n становится достаточно большим.

0 голосов
/ 28 октября 2010

Существует алгоритм пакета карт: вы создаете упорядоченный массив чисел («пакет карт») и на каждой итерации выбираете из него случайное число (естественно, удаляя выбранный номер из «пакета карт»)..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...