![6f525f73da3cc8c38f533fea519ea031.png](https://img-blog.csdnimg.cn/img_convert/6f525f73da3cc8c38f533fea519ea031.png)
Notation
- rand5()能够生成0-4的随机数
- rand7()能够生成0-6的随机数
已知rand7()生成rand5()
方法比较简单,只需要不断生成0-6的随机数,小于5则返回即可
int rand5()
{
int res=rand5();
while(res>4)
{
res = rand5();
}
return res;
}
已知rand5()生成rand7()
这里就要考虑如何使用rand5()生成大于4的随机数 - 简单的使用rand5()×2之类的操作肯定是不行了,这只会让随机数由0-4变成0,2,4,8 - 使用rand5()+rand5()呢?似乎确实覆盖了0-8,但是0-8数字概率并不均衡,例如0的可能只有0+0,但是2的可能有1+1,0+2,2+0三种,因此并不是真的均匀随机 - 综上,使用rand5()+rand5()×5,rand5()是0,1,2,3,4的随机,rand5()×5是0,5,10,15,20的随机,因此对于0-24的所有数字的取样,都是等概率的,其实对于任意randn(),都可以通过randn()×n+randn()来扩展随机数范围
然而问题并没有结束,尽管我们生成了一个rand25(),但采用上述方法获取rand7()会消耗大量的时间,因此不能消极等待小于7的随机数的出现。
我们想到,可以使用rand25()%7来得到rand7(),但是这样又会导致概率不均衡,因此采用rand25()来生成rand21(),这个21是根据$25/7*7$计算得到,再用rand21()对7取余来生成rand7(),代码如下:
int rand7()
{
int res = rand5()*5 + rand5();
while(res>20)
{
res = rand5()*5 + rand5();
}
return res%7;
}