Code C / C ++ le code principal n'a qu'une seule ligne!
static unsigned int gi = 0;
int rand7()
{
return (((rand() % 5 + 1) + (gi++ % 7)) % 7) + 1;
}
//call this seed before rand7
//maybe it's not best seed, if yo have any good idea tell me please
//and thanks JiminP again, he remind me to do this
void srand7()
{
int i, n = time(0);
for (i = 0; i < n % 7; i++)
rand7();
}
Le srand7 () est la graine de rand7, doit appeler cette fonction avant rand7, tout comme appeler srand avant rand en C.
C'est un très bon choix, car il n'appelle rand () qu'une seule fois, et aucune boucle, aucune dépense de mémoire supplémentaire.
Permettez-moi de l'expliquer: considérons un tableau entier de taille 5:
1st get one number from 1 2 3 4 5 by rand5
2nd get one number from 2 3 4 5 6
3rd get one number from 3 4 5 6 7
4th get one number from 4 5 6 7 1
5th get one number from 5 6 7 1 2
5th get one number from 6 7 1 2 3
7th get one number from 7 1 2 3 4
Nous avons donc obtenu le TABLEAU, chacun de 1-7 apparaît 5 fois dedans, et a tous les 35 nombres, donc la probabilité de chaque nombre est 5/35 = 1/7. Et la prochaine fois,
8th get one number from 1 2 3 4 5
9th get one number from 2 3 4 5 6
......
Après suffisamment de temps, nous pouvons obtenir la distribution uniforme de 1-7.
Ainsi, nous pouvons allouer un tableau pour restaurer les cinq éléments de 1-7 par boucle vers la gauche et obtenir un numéro du tableau à chaque fois par rand5. Au lieu de cela, nous pouvons générer les sept tableaux avant et les utiliser de manière circulaire. Le code est également simple, a de nombreux codes courts peuvent le faire.
Mais, nous pouvons utiliser les propriétés de l'opération%, donc le tableau 1-7 lignes est équivalent à (rand5 + i)% 7, c'est-à-dire: a = rand ()% 5 + 1 est rand5 en langage C, b = gi ++ % 7 génère toutes les permutations du tableau ci-dessus, et 0 - 6 remplace 1 - 7 c = (a + b)% 7 + 1, génère 1 - 7 uniformément. Enfin, nous avons obtenu ce code:
(((rand() % 5 + 1) + (gi++ % 7)) % 7) + 1
Mais, nous ne pouvons pas obtenir 6 et 7 au premier appel, nous avons donc besoin d'une graine, certains comme srand pour rand en C / C ++, pour perturber la permutation pour le premier appel formel.
Voici le code complet à tester:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
static unsigned int gi = 0;
//a = rand() % 5 + 1 is rand5 in C language,
//b = gi++ % 7 generates all permutations,
//c = (a + b) % 7 + 1, generates 1 - 7 uniformly.
//Dont forget call srand7 before rand7
int rand7()
{
return (((rand() % 5 + 1) + (gi++ % 7)) % 7) + 1;
}
//call this seed before rand7
//maybe it's not best seed, if yo have any good idea tell me please
//and thanks JiminP again, he remind me to do this
void srand7()
{
int i, n = time(0);
for (i = 0; i < n % 7; i++)
rand7();
}
void main(void)
{
unsigned int result[10] = {0};
int k;
srand((unsigned int)time(0)); //initialize the seed for rand
srand7() //initialize the rand7
for (k = 0; k < 100000; k++)
result[rand7() - 1]++;
for (k = 0; k < 7; k++)
printf("%d : %.05f\n", k + 1, (float)result[k]/100000);
}