Générer nombre aléatoirement

Résolu/Fermé
stark173 Messages postés 105 Date d'inscription vendredi 26 juillet 2013 Statut Membre Dernière intervention 6 février 2015 - 10 déc. 2013 à 15:15
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 - 11 déc. 2013 à 17:05
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.
A voir également:

1 réponse

[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié par [Dal] le 10/12/2013 à 15:47
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éclaration
int 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 le
while
).

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 le
while
).

Cela évite d'avoir à parcourir
int 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 code
srand(time(NULL));
devrait être à l'extérieur de la boucle
for
. Une seule initialisation du générateur de nombres aléatoires devrait être faite.

Enfin, tu devrais mettre
#include <stdio.h>
pour ton
printf
.


Dal
0
stark173 Messages postés 105 Date d'inscription vendredi 26 juillet 2013 Statut Membre Dernière intervention 6 février 2015
10 déc. 2013 à 15:46
Merci beaucoup, c'est plus clair !
0
Bruce Willix Messages postés 11968 Date d'inscription mardi 24 mai 2011 Statut Contributeur Dernière intervention 12 juin 2018 2 587
10 déc. 2013 à 15:50
Question de Novice, mais c'est pas "plus aléatoire" si tu réinitialises le générateur à chaque tirage ?
0
stark173 Messages postés 105 Date d'inscription vendredi 26 juillet 2013 Statut Membre Dernière intervention 6 février 2015
10 déc. 2013 à 16:01
Comment ça?
0
Bruce Willix Messages postés 11968 Date d'inscription mardi 24 mai 2011 Statut Contributeur Dernière intervention 12 juin 2018 2 587
10 déc. 2013 à 16:14
C'est rapport à la remarque de Dal:
 Une seule initialisation du générateur de nombres aléatoires devrait être faite. 
0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié par [Dal] le 10/12/2013 à 16:41
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" dans
srand
- "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 initialiser
srand
, on utilise en général
time(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
0