2010-03-15 8 views
13
srand(time(NULL)); 
    for(i = 0; i < n; i++){ 
      for(j = 0; j < (n-1); j++){ 
       a[i][j] = rand(); 
      } 
     } 

Я пытаюсь генерировать случайные числа, но они одинаковы ... Что мне делать?Случайные числа в C

Объявление массива:

int** a; 
int i; 
printf("Enter array size: "); 
scanf("%d", &n); 

a = (int**)calloc(n, sizeof(int)); 
for(i = 0; i < n; i++) 
    a[i] = (int*)calloc(n-1, sizeof(int)); 
+2

Ваш первый 'calloc' вызов должен быть' SizeOf (INT *) ', но вы, кажется, работает на хосте, где простые указатели и Интс имеют одинаковый размер (это верно для большинства архитектур). – mpez0

ответ

20

Вызов srand() вне цикла. Вы пересаживаете его на каждую итерацию.

srand() содержит генератор случайных чисел, поэтому вы получаете различную последовательность случайных чисел в зависимости от ввода. Ваш цикл работает очень быстро, поэтому вызов time(NULL) всегда возвращает то же значение. С каждой итерацией вы возвращаетесь к одной и той же случайной последовательности. Как правило, звоните только srand() один раз в вашу программу.

+0

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

+0

@bta: true, что вам не нужно будет семять 'rand()' более одного раза. Другое дело - повторное сеяние «правильных» генераторов случайных чисел, под которыми я подразумеваю все, что используется для обеспечения безопасности. –

6

Не звоните srand() каждый раз через цикл - просто сделайте это один раз заранее.

2
srand(time(NULL)); 

for(i = 0; i < n; i++){   
     printf("%d ", time(NULL)); 
     for(j = 0; j < (n-1); j++){ 
      a[i,j] = rand(); 
     } 
    } 

Звонок сперва один раз за пределы цикла.

+0

Это не помогает –

3

srand - это функция, которая «семена» генератора случайных чисел. Если вы не знаете, случайные числа на компьютерах не являются случайными. Фактически, компьютер просто имеет список чисел, которые кажутся случайными в нем, и вы используете srand, чтобы сообщить, с чего начать в этом списке, при каждом вызове rand(), возвращая следующий элемент в списке.

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

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

1

Перед входом в цикл необходимо позвонить srand(). srand() инициализирует генератор числа Radnom с заданным семенем и генерирует уникальную последовательность случайных чисел для этого семени.

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

4

ЧАСТО ЗАДАВАЕМЫЕ ВОПРОСЫ 13.15 к 13.20 будет представлять интерес. И у меня возникает соблазн создать новый тег для таких вопросов.

+0

Возможно, создайте один вопрос под названием «как srand() влияет на состояние генератора случайных чисел?», И отмечайте его как дубликат каждый раз, когда появляется еще одна тонкая вариация ;-) –

+0

Да, версия CW , Но тогда мы будем копировать все comp.lang. *. Faqs, не так ли? – dirkgently

+1

Да, но SO неизбежно будет содержать множество дубликатов часто задаваемых вопросов (по определению F), поэтому будет дублировать comp.lang. *. Faq, что бы вы ни делали. Если вопросы безжалостно отмечены как дубликаты, хотя, даже если они немного изменят тему, они получат меньше информации, чем существующие часто задаваемые вопросы (при условии, что ответы на них часто затрагивают). CW-версия часто задаваемых вопросов, которые также являются F на SO, может быть помечена как таковая, а также ссылаться на часто задаваемые вопросы по языку и любые другие соответствующие ресурсы и может рассматшать этот вопрос самым общим способом, чтобы обеспечить их максимальное совпадение. Или что-то. –

0
srand(time(NULL)); 
for(i = 0; i < n; i++){ 
    for(j = 0; j < (n-1); j++){ 
     a[i,j] = rand(); 
    } 
} 

Неважно. Число одни и те же ...

+0

Что это за синтаксис 'a [i, j]'? Вы хотите 'a [i] [j]', возможно, хотя вы должны получать ошибку компилятора, если j - это простой массив вместо 2-D массива, как я уверен, вы намерены. – indiv

+0

У меня нет ошибки .. но нульмеры такие же ... –

+0

Показать объявление 'a'. – indiv

0
int** a; 
int i; 
printf("Enter array size: "); 
scanf("%d", &n); 
if(n < 1){ 
    printf("Size should be > 0\n\n"); 
    return NULL; 
} 
a = (int**)calloc(n, sizeof(int)); 
for(i = 0; i < n; i++) 
    a[i] = (int*)calloc(n-1, sizeof(int)); 

Вот мой массив ...

+1

Во-первых, вы должны отредактировать свое сообщение, чтобы добавить эту новую информацию. Этот сайт не работает как форум. Во-вторых, я согласен с тем, что ваш двухмерный синтаксис массива неверен, и вы должны делать 'a [i] [j]' при доступе к элементу. Ниже приведено многомерное руководство по массиву: http://www.functionx.com/cpp/Lesson12.htm – indiv

+0

Вам не нужно выделять «(int **)» при написании кода C :). –

+0

i do 'a [i] [j]', но это не помогает .. –

0

Сергей, вы не получите сообщение об ошибке с a[i,j] версии просто потому, что это совершенно правильное выражение. Оператор запятой оценивает подвыражения слева направо и возвращает значение последнего выражения. Таким образом, запись a[i,j] идентична a[j]. То, что вы получили в печати, было значением указателя на j-й вектор в вашей матрице.

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