题目:
假设有两个函数 rand3()可以产生随机的0、1、2,rand5()可以产生随机的0、1、2、3、4,现在请你利用它编写一个函数rand7(),产生0~6的随机数。
方法1:利用数组
int rand7()
{
int a[3][3]={ 0,1,2,3,4,5,6,7,8 };
int row,col;
do
{
row = rand3();
col = rand3();
} while(a[row][col]>6);
return a[row][col];
}
方法2:利用switch语句
int rand7()
{
int re;
do
{
switch( rand3() )
{
case 0:
re = rand3();
break;
case 1:
re = rand3()+3;
break;
case 2:
re = rand3()+6;
break;
}
} while(re>6);
return re;
}
方法3:更简洁,实质和方法2相同
int rand7()
{
int re;
do
{
re = rand3()+rand3()*3;
}while(re>6);
return re;
}
测试代码:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int rand5()
{ return rand()%5; }
int rand3()
{ return rand()%3; }
int rand7()
{
int a[3][3]={ 0,1,2,3,4,5,6,7,8 };
int row,col;
do
{
row = rand3();
col = rand3();
} while(a[row][col]>6);
return a[row][col];
}
//从均匀的0~20里面取mod
int rand7a() {
int sum = 0;
for (int i=0;i<7;i++) {
sum+= rand3()+i*3;
}
return sum%7;
}
//从均匀的0~34里面取mod
int rand7b() {
int sum = 0;
for(int i=0;i<7;i++) {
sum += rand5()+i*5;
}
return sum%7;
}
void main()
{
int re[7]={0};
srand( (unsigned)time( NULL ) );
for(int i=0;i<1000000;i++)
{
re[rand7()]++;
}
for(int i=0;i<7;i++)
printf("re[%d]=%d,%2d%%\n",i,re[i],int(re[i]*100/1000000.0+0.5));
}
运行结果:
re[0]=143047, 14%
re[1]=143042, 14%
re[2]=143561, 14%
re[3]=143315, 14%
re[4]=142750, 14%
re[5]=142144, 14%
re[6]=142141, 14%
请按任意键继续. . .
错误方法:
//从均匀的0~20里面取mod
int rand7a() {
int sum = 0;
for (int i=0;i<7;i++) {
sum+= rand3()+i*3;
}
return sum%7;
}
//从均匀的0~34里面取mod
int rand7b() {
int sum = 0;
for(int i=0;i<7;i++) {
sum += rand5()+i*5;
}
return sum%7;
}
错误方法分析:
- rand7a()在测试时就发现产生数字的概率不平均,rand7b()在测试时产生的概率是平均的,而这两种方法的原理相同,为什么会这样?
- rand7a()中加到sum中的数字之和为:0+3+6+…+18=63,63%7=0,所以实质是sum=7个rand3()之和。sum有 37=2178 个结果,不是7的倍数,概率是不平均的。
- rand7b()原理是一样的,所以概率也是不平均的。但在测试时结果是平均的,可能是因为sum有 57=78125 个结果,必须增大测试数据量才行。
- 在实际测试时用了900000000个数据,rand7b()的结果概率仍然平均的。不知道是为什么?如果哪位网友找到了原因,请留言,分享一下。
参考:
本文是根据在CSDN问答频道和网友讨论一个问题的帖子整理而成。
该贴链接

2884

被折叠的 条评论
为什么被折叠?



