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

Provo a generare numeri casuali, ma sono uguali ... Cosa devo fare?Numeri casuali in C

dichiarazione Array:

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

Il tuo primo 'chiamata calloc' dovrebbe essere' sizeof (int *) ', ma ti sembra di essere al lavoro su un host in cui i puntatori semplici e interi sono della stessa dimensione (questo è vero per la maggior parte delle architetture). – mpez0

risposta

20

chiamata srand() al di fuori del ciclo. Stai riesaminando ogni iterazione.

srand() semina il generatore di numeri casuali in modo da ottenere una sequenza diversa di numeri casuali a seconda dell'input. Il ciclo viene eseguito molto velocemente, quindi la chiamata a time(NULL) restituisce sempre lo stesso valore. Stai ripristinando la stessa sequenza casuale ad ogni iterazione. Come regola generale, chiami solo srand() una volta nel tuo programma.

+0

Concordato, tu (generalmente) non dovresti aver bisogno di seminare un generatore di numeri casuali più di una volta. – bta

+0

@bta: true che non dovresti aver bisogno di seminare 'rand()' più di una volta. Ri-seminare generatori di numeri casuali "appropriati", con cui intendo qualsiasi cosa usato per la sicurezza, è un'altra questione. –

6

Non chiamare il numero srand() ogni volta attraverso il ciclo: è sufficiente farlo prima.

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(); 
     } 
    } 

Chiama srand una volta fuori dal ciclo.

+0

non aiuta –

3

srand è una funzione che "semina" il generatore di numeri casuali. Nel caso non lo sapessi, i numeri casuali nei computer non sono casuali. In effetti, il computer ha solo un elenco di numeri che sembrano casuali e si utilizza srand per indicare da dove iniziare in quell'elenco, con ogni chiamata a rand() restituendo l'elemento successivo nell'elenco.

La ragione per cui si scrive srand(time(NULL)) consiste nell'avviare i numeri casuali in un punto che non sarà uguale ogni volta che si esegue il programma (a meno che i programmi non si avviino contemporaneamente).

Quindi, quello che stai facendo qui sta dicendo ripetutamente al programma di riavviare l'elenco di numeri casuali nello stesso punto (perché il tempo è lo stesso ogni volta che si passa attraverso il ciclo). Sposta la chiamata a srand fuori dal ciclo e otterrai i risultati corretti.

1

È necessario chiamare srand() prima di entrare nel ciclo. srand() inizializza il generatore di numero radnom con il seme specificato e genera una sequenza univoca di numeri casuali per questo seme.

Il ciclo viene eseguito molto velocemente, quindi ogni chiamata a time(NULL) produce lo stesso tempo (misurato in secondi) - quindi si inizializza il generatore di numeri casuali con lo stesso seme per ogni iterazione del ciclo.

4

Domande frequenti 13.15 a 13.20 sarà di interesse. E sono tentato di creare un nuovo tag per tali domande.

+0

Forse creare una domanda singola intitolata "come srand() influenza lo stato del generatore di numeri casuali?", E contrassegnarlo come duplicato ogni volta che si verifica un'altra variazione sottile ;-) –

+0

Sì, una versione CW . Ma poi dovremmo duplicare tutte le comp.lang. *. Faqs, no? – dirkgently

+1

Sì, ma SO conterrà inevitabilmente una miriade di duplicati di domande frequenti (per definizione di F), quindi duplicherà comp.lang. *. Faq qualunque cosa tu faccia. A meno che le domande non siano contrassegnate spietatamente come duplicati, anche se variano un po 'il tema, finiranno con meno informazioni rispetto alle FAQ esistenti (supponendo che le FAQ lo coprano bene). La versione CW delle domande frequenti che sono anche F su SO potrebbe essere taggata come tale e collegarsi alle FAQ della lingua e ad altre risorse pertinenti, e potrebbe formulare la domanda nel modo più generale, per garantire che catturino il maggior numero di volte. O qualcosa. –

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

Non importa. Il numero è lo stesso ...

+0

Cos'è questa sintassi 'a [i, j]'? Tu vuoi 'a [i] [j]', probabilmente, anche se dovresti ottenere un errore del compilatore a meno che j non sia un semplice array invece di un array 2-D come sono sicuro che tu intenda. – indiv

+0

Non ho avuto errore .. ma i nubmers sono uguali ... –

+0

Mostra la dichiarazione di '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)); 

Qui è la mia serie ...

+1

Innanzitutto, è necessario modificare il post per aggiungere queste nuove informazioni. Questo sito non funziona come un forum. In secondo luogo, sostengo la mia affermazione secondo cui la sintassi dell'array 2-D è errata e dovresti fare 'a [i] [j]' quando accedi ad un oggetto. Ecco un tutorial di array multidimensionale: http://www.functionx.com/cpp/Lesson12.htm – indiv

+0

Non è necessario eseguire il cast "(int **)" durante la scrittura del codice C :). –

+0

faccio 'a [i] [j]', ma non aiuta .. –

0

Sergey, non hai un messaggio di errore con la versione a[i,j] semplicemente perché questo è un'espressione perfettamente valido. L'operatore virgola valuta le sottoespressioni da sinistra a destra e restituisce il valore dell'ultima espressione. Pertanto, la scrittura a[i,j] è identica a a[j]. Quello che hai ricevuto nella stampa era il valore del puntatore al vettore j-th nella tua matrice.