用c语言实现小随机数产生大随机数
给定能随机生成整数1到5的函数,写出能随机生成整数1到7的函数
方法一:
a.随机一个值value(1-5)
b.随机一个值temp(1-5),如果temp<3把value从1-5映射到6-10,如果temp=3再随机一次temp(为了公平)
c.如果value>7则丢弃,从a开始。得到符合要求的数
int rand7a ( void ) { int value, temp; do { value = rand5 (); while (3 == (temp = rand5 ())) ; if (temp < 3) value += 5; }while (value > 7); return value; } /* ----- end of function rand7a ----- */
方法二:
思路和方法一差不多
5个随机值(1-5)之和的范围为1-25,把大于21的丢弃,剩下的用7取余加一缩小到需求范围
int rand7b ( void ) { int value; do { value = rand5() + rand5() + rand5() + rand5() + rand5(); }while (value > 21); return 1 + value % 7; } /* ----- end of function rand7b ----- */
方法三:
51jobdoc里面提供的办法,总感觉比较二
http://www.51jobdoc.com/TypeDesign/InfoDetails.aspx?id=169&tid=12
此题的关键是让生成的 1 到 7 的数出现概率相同。
只要我们可以从 n 个数中随机选出 1 到 n 个数,反复进行这种运算,直到剩下最后一个数即可。
我们可以调用 n 次给定函数,生成 n 个 1 到 5 之间的随机数,选取最大数所在位置即可满足以上要求。
例如
初始的 7 个数 [1,2,3,4,5,6,7].
7 个 1 到 5 的随机数 [5, 3,1,4,2,5,5]
那么我们保留下[1,6,7],
3 个1 到 5 的随机数[2,4,1]
那么我们保留下[6]
6 就是我们这次生成的随机数。
int rand7c ( void ) { int arr[7] = {0,0,0,0,0,0,0}; int index, value, count, max; do { for (index = 0; index < 7; index++) if (0 == arr[index]) arr[index] = rand5 (); for (index = 0, max = 0; index < 7; index++) if (arr[index] > max) max = arr[index]; for (index = 0, count = 0; index < 7; index++) if (arr[index] < max) arr[index] = -1; else { arr[index] = 0; value = index + 1; count++; } }while (count != 1); return value; } /* ----- end of function rand7c ----- */
方法四:
搞一个7元素数组,不断填充随机值,直到只有只有一个元素等于5的时候把元素的位置当作新随机值(1-7)
int rand7d ( void ) { int arr[7]; int index, value; int count = 0; do { for (index = 0, count = 0; index < 7; index++) if(5 == (arr[index] = rand5 ())) { count++; value = index + 1; } }while (count != 1); return value; } /* ----- end of function rand7d ----- */
方法五:
用数组随机数组坐标来取值。这个没什么好解释的,如果要的不是1-7 而是1-100,就需要用三维数组来产生。
int rand7e ( void ) { static int arr[5][5] = { {1, 2, 3, 4, 5}, {6, 7, 1, 2, 3}, {4, 5, 6, 7, 1}, {2, 3, 4, 5, 6}, {7, 0, 0, 0, 0} }; int value = 0; while (0 == (value = arr[rand5() - 1][rand5() - 1])) ; return value; } /* ----- end of function rand7e ----- */
1-5随机函数
由于5相对于RAND_MAX很小 所以取余加一符合要求
int rand5 ( void ) { return rand () % 5 + 1; } /* ----- end of function rand5 ----- */
测试
void test ( int (*func) (void), int times ) { int result[7] = {0, 0, 0, 0, 0, 0, 0}; int index; for (index = 0; index < times; index++) result[func () - 1]++; printf ("number:"); for (index = 1; index < 8; index++) printf ("%-7d", index); printf ("\ncount :"); for (index = 0; index < 7; index++) printf ("%-7d", result[index]); puts (""); return ; } /* ----- end of function test ----- */
每个随机数生成函数测试35000次
#include <stdlib.h> #include <stdio.h> #include <time.h> int rand5 (void); int rand7a (void); int rand7b (void); int rand7c (void); int rand7d (void); int rand7e (void); void test (int (*func) (void), int times); int main ( int argc, char *argv[] ) { srand ((unsigned int) time (NULL)); puts ("Using rand5 ()"); test (rand5, 35000); puts ("\nUsing rand7a ()"); test (rand7a, 35000); puts ("\nUsing rand7b ()"); test (rand7b, 35000); puts ("\nUsing rand7c ()"); test (rand7c, 35000); puts ("\nUsing rand7d ()"); test (rand7d, 35000); puts ("\nUsing rand7e ()"); test (rand7e, 35000); return EXIT_SUCCESS; } /* ---------- end of function main ---------- */
测试结果:
[leajon@arch random]$ ./random Using rand5 () number:1 2 3 4 5 6 7 count :6955 7062 7007 6976 7000 0 0 Using rand7a () number:1 2 3 4 5 6 7 count :4867 5037 4978 4947 5059 5028 5084 Using rand7b () number:1 2 3 4 5 6 7 count :5153 4714 4985 4940 5045 5101 5062 Using rand7c () number:1 2 3 4 5 6 7 count :4981 5107 4980 5008 4928 5016 4980 Using rand7d () number:1 2 3 4 5 6 7 count :4925 4943 5001 5062 5029 5045 4995 Using rand7e () number:1 2 3 4 5 6 7 count :5085 5053 4950 4949 4955 5045 4963
结果还算满意。。