题目描述:用rand_7实现rand_3,rand_23,rand_49。rand_7随机生成[1,7]的整型数据。
可以证明通过截短rand_3()可以等概率生成随机数。
int rand_3()
{
int tmp = 0;
while(tmp = rand_7())
{
if(tmp <= 3)
return tmp;
}
}
int rand_49()
{
return ( 7 * (rand_7() - 1) + rand_7() );
}
int rand_23()
{
int tmp = 0;
while ( tmp = 7 * ( rand_7() - 1 ) + rand_7() )
{
// if(tmp <= 23)
// 使得有更高的概率跳出循环,减少循环次数。选取最接近49的23的倍数。
if(tmp <= 46)
return (tmp % 23 + 1);
}
}
更加一般的结论:
对于a < b,一定可以用rand_b来生成rand_a,rand_a(输出在[1,a]的随机数!!
对于a > b,可以用 b*(rand_b-1)+rand_b来生成,若不够还可以用b^2*(rand_b-1)+rand_b...!!
之后用 int(b^2/a)*a 最接近的整数来增大截短概率,避免无限循环。
扩展:给你rand_a和rand_b,生成rand_ab(),在[1, a*b]之间的随机数。
int rand_a_b()
{
// return (b * (rand_a() - 1) + rand_b());
return (a * (rand_b() - 1) + rand_a());
}
思路:由rand_a_b生成[1,b-a+1],比较 (b-a+1) vs (d-c+1),利用前边的结论一定可以生成[1,d-c+1]之间的随机数,加上c-1即可生成[c,d]之间的随机数。
参考了网上的一些文章,自己写的小结和代码(完全是自己码的)。