2010-11-06 10 views
2

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

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

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

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

+1

Редактировать Ваш вопрос: Выберите код, а затем нажмите кнопку "101 010". –

+0

Сторона уведомления - почему '(без знака) (NULL)' ??? 0 не работает для вас? – a1ex07

+0

Вы всегда можете сохранить произвольно сгенерированные числа в стеке. Затем проверьте, находится ли новый rand в стеке. Если это так, сгенерируйте новый номер и снова проверьте. –

ответ

2

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

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

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

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

#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 
2

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

  • Создать массив с каждым номером
  • Выберите случайный индекс I между 0 и X, и получить его значение
  • Move X значение в I положение
  • Уменьшить X и повторить
+0

+1 Прекрасное простое решение для лотереи, как проблема. – rturrado

1

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

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

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

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

+0

+1 Чтобы «увеличить» ваш ответ –

3

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

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

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

Смежные вопросы