Ваш код имеет один из страннее отступов и компоновочных схем скобки я когда-либо видел:
#include <stdio.h>
#include <stdlib.h>
int getRandomNumber(int Min, int Max)
{
double rnd= (double)rand()/((double)RAND_MAX+1);
return (int)(rnd*(Max-Min+1))+Min;
}
int main()
{
int j,counter,temp,deck[13];
srand(time(NULL));
int i;
counter=1;
for (i=0;i<12;i++)
{deck[i]=-1;
temp = getRandomNumber(0,81);
for (j=0;j<=i;j++)
{if (temp==deck[j])
{counter=0;}
if (counter!=0)
deck[i]=temp;
}
}
for(i=0;i<12;i++)
printf("%d ",deck[i]);
}
конвертируется в более ортодоксальный стиль (Allman, более или менее - см Википедии на Indent style) , вы получите:
#include <stdio.h>
#include <stdlib.h>
static int getRandomNumber(int Min, int Max)
{
double rnd = (double)rand()/((double)RAND_MAX + 1);
return (int)(rnd * (Max - Min + 1)) + Min;
}
int main(void)
{
int j, counter, temp, deck[13];
srand(time(NULL));
int i;
counter = 1;
for (i = 0; i < 12; i++)
{
deck[i] = -1;
temp = getRandomNumber(0, 81);
for (j = 0; j <= i; j++)
{
if (temp == deck[j])
{
counter = 0;
}
if (counter != 0)
deck[i] = temp;
}
}
for (i = 0; i < 12; i++)
printf("%d ", deck[i]);
}
static
и int main(void)
необходимы, чтобы получить код мимо моих вариантов компиляции по умолчанию; в противном случае они косметические.
Теперь мы можем видеть некоторые проблемы. counter
устанавливается на 1
один раз, вне внешнего контура; он устанавливается в 0
, иногда внутри цикла, но как только это произойдет, он никогда не будет сброшен до 1
, поэтому дополнительные номера не добавляются к deck
. Вам нужно переделать внутренний цикл, может быть, как это:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
static int getRandomNumber(int Min, int Max)
{
double rnd = (double)rand()/((double)RAND_MAX + 1);
return (int)(rnd * (Max - Min + 1)) + Min;
}
int main(void)
{
int deck[13];
srand(time(NULL));
for (int i = 0; i < 12; i++)
{
int temp = getRandomNumber(0, 81);
deck[i] = -1;
int counter = 1;
for (int j = 0; j <= i; j++)
{
if (temp == deck[j])
{
counter = 0;
break;
}
}
if (counter != 0)
deck[i] = temp;
else
i--; // Try again with a new random choice for the same i
}
const char *pad = "";
for (int i = 0; i < 12; i++)
{
printf("%s%d", pad, deck[i]);
pad = " ";
}
putchar('\n');
return 0;
}
Мне не нравится хвостовые пробелы, так что цикл печати заботится, чтобы обеспечить их нет.
Пример вывода с getRandomNumber()
- на MacOS Сьерра 10.12.2 с GCC 6.3.0:
7 73 38 61 11 13 41 66 29 39 72 20
7 2 18 17 54 31 45 40 34 22 63 16
7 13 80 54 16 49 14 58 28 53 23 26
7 24 60 10 67 53 69 32 23 2 66 12
7 34 40 48 21 3 57 43 6 18 27 80
7 45 20 3 65 21 61 17 12 69 66 27
7 67 62 78 70 57 68 46 9 2 72 39
7 77 41 34 32 75 72 20 64 78 33 25
7 6 21 72 76 11 75 38 73 27 64 33
7 17 1 27 37 28 80 49 12 67 59 36
Это первый номер не очень случайно - вскоре после этой последовательности испытаний, она изменилась с 7 до 8 , но был одинаково неслучайным. Альтернативный способ генерации случайных чисел является:
static int getRandomNumber(int Min, int Max)
{
int rnd;
int range = (Max - Min + 1);
while ((rnd = rand()) > RAND_MAX - (RAND_MAX % range))
;
return (rnd % range) + Min;
}
Это позволяет избежать смещения от того факта, что 82 не делится RAND_MAX точно, что бы утяжелить распределение нижних чисел немного выше, чем верхние числа в диапазон 0..81. Он также избегает неожиданно непротиворечивого первого номера, хотя новый первый номер также является полурепрессивным, когда тесты выполняются с интервалом в 1 секунду.
Примеры результатов:
48 33 28 78 14 2 81 13 23 75 38 40
45 42 74 1 11 68 17 33 78 49 23 80
42 51 38 3 5 52 35 56 54 23 59 41
39 60 2 8 36 53 79 30 72 75 62 37
36 69 45 10 78 20 71 17 6 53 54 30
33 78 9 15 75 7 40 61 27 36 70 68
30 5 55 17 69 73 25 63 37 1 21 71
27 14 19 66 57 43 1 13 3 65 71 21
24 26 62 63 41 61 68 28 67 20 74 17
21 35 26 57 28 79 47 44 2 52 60 77
Обратите внимание, что первое число уменьшается на 3; второй, похоже, увеличивается на 9; тьфу - случайность не так уж и хороша. Хорошо известно, что rand()
часто не является высококачественным PRNG (генератором псевдослучайных чисел), но я немного удивлен этим, по-видимому, систематическим поведением с семенами, которые каждый раз отличаются на 1.
На моем Mac, когда я изменил srand()
к srandom()
и rand()
к random()
, я лучше (как, более непредсказуемым) результаты:
29 1 7 11 25 52 63 15 26 55 75 64
40 4 64 18 8 57 73 27 38 15 60 28
43 3 27 17 1 58 26 72 73 18 20 7
76 16 27 43 64 20 63 30 35 17 33 57
79 47 32 33 6 30 35 7 38 55 25 61
69 57 79 75 15 54 5 35 21 46 65 61
30 79 66 14 56 39 19 8 50 47 76 33
62 65 81 44 52 39 25 30 54 12 24 68
27 49 60 72 53 35 14 41 63 46 45 65
67 39 9 11 60 19 64 73 43 17 21 26
И страница людей Mac для random()
еще предлагает использовать arc4random()
вместо , но это намного лучше, чем просто rand()
. То, что вы найдете в других системах, будет зависеть от возможностей, предоставляемых системой - rand()
может быть не таким ужасным, как кажется на Mac. В принципе, будьте осторожны с выбором PRNG - особенно если вы собираетесь использовать систематически созданные семена (например, текущее время).
Здесь очень много вопросов о выборе уникального номера. Один из способов состоит в том, чтобы начать с массива доступных чисел, произвольно выбрать индекс массива * и удалить этот элемент из массива. Вот [один такой ответ] (http://stackoverflow.com/a/27867571/4142924). –
Если вы уже знаете домен вашего нужного набора чисел (0..81), почему бы просто не загрузить последовательность этих 82 значений, а затем сделать простой [Fisher-Yates shuffle] (https: //en.wikipedia .org/wiki/Fisher% E2% 80% 93Yates_shuffle). – WhozCraig
вопрос говорит о числах МЕЖДУ 0 и 81 I.E. 1 ... 80. Вы можете использовать этот оператор: 'value = (rand()% 80) +1;', Если вам не нужны какие-либо повторяющиеся числа, то с каждым новым значением «искать» массив, чтобы убедиться, что он еще не находится в массиве перед тем как вставить новое значение в массив. – user3629249