Générer nombre aléatoirement
Résolu
stark173
Messages postés
160
Statut
Membre
-
[Dal] Messages postés 6122 Date d'inscription Statut Contributeur Dernière intervention -
[Dal] Messages postés 6122 Date d'inscription Statut Contributeur Dernière intervention -
Bonjour, un amis m'a prété son code pour que je réalise un système de loterie.
Pour l'instant, il permet juste de générer des nombres aléatoirement.
Voici son code:
#include <stdlib.h>
#include <conio.h>
#include <time.h>
#define MAX 90
int main(void)
{int tab[MAX]={0},i,numerotire, tirage;
int num[MAX]={0};
for(i=0;i<MAX;i++)
{srand(time(NULL));
tab[i]=rand() % MAX;
numerotire=tab[i];
while(num[numerotire]==1) //Si jamais on avait déjà entrée cette valeur, on recommence
{tab[i]=rand() % MAX;
numerotire=tab[i];}
printf("Le numero tire est : %d\n",numerotire);
num[numerotire]=1; /*on entre 1 dans le 2eme tableau si c'est un nombre qu'on utilise pour la 1ere fois, si non il y a un zéro*/}
}
La première chose que je ne comprend pas, est la boucle while: pourquoi faire appel à un deuxième tableau et pourquoi le tableau prend la valeur 1?
Cette ligne est également visible à la fin du code mais je ne la comprend pas mieux; merci de me venir en aide.
Pour l'instant, il permet juste de générer des nombres aléatoirement.
Voici son code:
#include <stdlib.h>
#include <conio.h>
#include <time.h>
#define MAX 90
int main(void)
{int tab[MAX]={0},i,numerotire, tirage;
int num[MAX]={0};
for(i=0;i<MAX;i++)
{srand(time(NULL));
tab[i]=rand() % MAX;
numerotire=tab[i];
while(num[numerotire]==1) //Si jamais on avait déjà entrée cette valeur, on recommence
{tab[i]=rand() % MAX;
numerotire=tab[i];}
printf("Le numero tire est : %d\n",numerotire);
num[numerotire]=1; /*on entre 1 dans le 2eme tableau si c'est un nombre qu'on utilise pour la 1ere fois, si non il y a un zéro*/}
}
La première chose que je ne comprend pas, est la boucle while: pourquoi faire appel à un deuxième tableau et pourquoi le tableau prend la valeur 1?
Cette ligne est également visible à la fin du code mais je ne la comprend pas mieux; merci de me venir en aide.
1 réponse
-
Salut stark173,
Le 2ème tableau, comme indiqué par le commentaire, permet de savoir (rapidement) si le numéro a déjà été tiré.
Lors de la déclarationint num[MAX]={0};, le tableau est mis à zéro.
Lorsqu'un numéro est tiré, le numéro tiré est utilisé comme index du tableau. Si la valeur est zéro, cela signifie qu'on n'a jamais tiré ce numéro, et on note qu'on l'a déjà tiré en mettant la valeur à 1 (c'est ce que fait le code implicitement après lewhile
).
Lors d'un prochain tirage, en accédant directement avec l'index à la position du tableau correspondant au numéro tiré, on sait immédiatement que le numéro a déjà été tiré si on constate que le contenu vaut 1 (et on refait un tirage, c'est ce que fait lewhile
).
Cela évite d'avoir à parcourirint tab[MAX]
pour vérifier, à chaque tirage, si le même numéro ne sort pas. Cette instantanéité de la vérification est au prix d'un espace mémoire double de celui normalement nécessaire.
C'est, en fait, une sorte de table de hachage.
Note aussi que, dans ton codesrand(time(NULL));
devrait être à l'extérieur de la bouclefor
. Une seule initialisation du générateur de nombres aléatoires devrait être faite.
Enfin, tu devrais mettre#include <stdio.h>
pour tonprintf
.
Dal-
-
-
-
-
Salut Bruce Willix,
c'est pas "plus aléatoire" si tu réinitialises le générateur à chaque tirage ?
En théorie oui, si un temps suffisant s'écoule entre deux appels à srand. En pratique, la réponse prudente est donc : non.
On passe à srand un entier permettant d'initialiser le générateur de nombre aléatoire (la "seed" qui est le "s" danssrand
- "graine aléatoire"). Pour une même "graine", le générateur de nombres aléatoires produira toujours la même séquence de nombres, car le même algorithme du générateur de nombres "aléatoires" sera utilisé sur la même valeur de départ.
Or, pour initialisersrand
, on utilise en généraltime(NULL)
, qui renvoie le nombre de secondes depuis epoch (00h00, 01-01-1970 UTC), comme c'est le cas dans ce code.
Cela a pour conséquence que tant qu'une seconde ne s'est pas écoulée, la réinitialisation de srand se fait avec la même valeur, et donc l'appel consécutif à rand() produira toujours le même chiffre.
Dal
-