C ++ генератор случайных чисел без повторяющихся чисел - PullRequest
2 голосов
/ 06 ноября 2010

Я искал верхний и нижний значения для функции, которая превращает этот код

#include <iostream>
#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

using namespace std;

void ran(int array[], int max);
int main() {
 printf("Today's lottery numbers are:\n");    
 for (int i = 0; i < 6; i++)
  srand((unsigned)(NULL));
}

в генератор случайных чисел, который гарантирует отсутствие повторяющихся чисел, может кто-нибудь помочь мне с этим?после проверки я планирую напечатать ее с printf("%d\n", rand()%50);

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

Спасибо.Библиотеки, кажется, не читают прямо на этом экране, но они stdio, stdlib и time, и я использую пространство имен.

Ответы [ 5 ]

3 голосов
/ 06 ноября 2010

Почему бы просто не использовать то, что уже есть в STL? Глядя на ваш пример кода и предполагая, что он в некоторой степени отражает то, что вы хотите сделать, все должно быть там. (Полагаю, вам нужен относительно небольшой диапазон чисел, чтобы память не была ограничением)

Использование std::random_shuffle и std::vector, содержащее целые числа в диапазоне, в котором вы хотите, чтобы ваши числа были, должны дать вам последовательность уникальных случайных чисел, которые вам нужны в вашем примере кода.

Вам все равно придется звонить srand один раз и только один раз, прежде чем использовать std::random_shuffle. Не так многократно, как в текущем примере кода.

2 голосов
/ 06 ноября 2010

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

  • Создать массив с каждым числом
  • Выберите случайный индекс I между 0 и X и получите его значение
  • Переместить X значение в I положение
  • Уменьшить X и повторить
2 голосов
/ 06 ноября 2010

Вы должны вызывать srand только один раз в своем коде, и вы должны называть это "случайным" начальным числом, например time(NULL).

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

Однако даже с этими исправлениями rand()%50 может дать вам одно и то же число дважды. То, что должен использовать, - это алгоритм случайного воспроизведения, подобный , этот , поскольку он работает точно так же, как лотерейные машины.

Вот полная программа, показывающая это в действии:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

static void getSix (int *dst) {
    int sz, pos, i, src[50];
    for (i = 0; i < sizeof(src)/sizeof(*src); i++)
        src[i] = i + 1;
    sz = 50;
    for (i = 0; i < 6; i++) {
        pos = rand() % sz;
        dst[i] = src[pos];
        src[pos] = src[sz-1];
        sz--;
    }
}
int main (void) {
    srand (time (NULL));
    int i, numbers[6];
    getSix (numbers);
    printf ("Numbers are:\n");
    for (i = 0; i < sizeof(numbers)/sizeof(*numbers); i++)
        printf ("   %d\n", numbers[i]);
    return 0;
}

Примеры прогонов:

Numbers are:
   25
   10
   26
   4
   18
   1
Numbers are:
   39
   45
   8
   18
   17
   22
Numbers are:
   8
   6
   49
   21
   40
   28
Numbers are:
   37
   49
   45
   43
   6
   40
1 голос
/ 06 ноября 2010

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

Проблема с rand() и попыткой предотвратить повторы состоит в том, что поиск неиспользуемого номера будет замедляться с каждым добавленным в список числом, что в конечном итоге станет очень длительным процессом поиска и удаления чисел.

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

Чтобы сделать это без использования каких-либо дополнительных библиотек, вы можете предварительно заполнить вектор или список последовательными (или даже случайными) числами, убедившись, что каждое число присутствует в списке один раз. Затем, чтобы сгенерировать число, сгенерируйте случайное число и выберите (и удалите) этот элемент из списка. Удаляя каждый элемент по мере его использования, при условии, что каждый элемент присутствовал один раз, вы никогда не столкнетесь с дубликатом.

0 голосов
/ 06 ноября 2010

И если у вас есть доступ к C ++ 0x, вы можете использовать новые возможности генератора случайных чисел, которые обернут весь этот мусор для вас!

http://www2.research.att.com/~bs/C++0xFAQ.html#std-random

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