给定一个随机数生成器randm(),获得randn()
第一种情况,n < m
根据数学推理,可以直接截取有效的部分,并且概率是相同的。
例如: 给出 rand7(),求 rand5():
int rand5(){
int x = ~(1 << 31);
while(x > 5)
x = rand7();
return x;
}
第二种写法:
int rand5(){
int x;
do{
x = rand7();
}while(x > 5)
return x;
}
第二种情况,m < n < m*m
例,给出 rand5(),求 rand7()
首先要声明,要看清题目怎么说的,比如 rand5() 是 0~5 还是 0~4 , 还是 1~4!!
我们假设这里 是 rand5() 生成 1,2,3,4,5
,rand7() 生成 1,2,3,4,5,6,7
想要获得均匀分布的[ 1 ,2,3,4,5,6,7]
,就要构建比它大的范围。
rand5() - 1
范围是 [0 ~ 4]
5 * (Rand5() - 1) + Rand5()
可以获得均匀分布的数字 ,范围 [1 ~ 25 ]。
这样就包含了[1 ~ 7]
再考虑到, 让 x 与 最接近25且小于25的7的倍数相比 ,于是 和 25/7*7
,即 21 作比较。
rand7(){
int i;
do{
i = 5 * (rand5() - 1 ) + rand5();
}while(i >= 21)
return i % 7 + 1;
}
-
如果上面 范围本来就是 [0,1 ....]
那就把
i = 5 * (rand5() - 1 ) + rand5();
改为i = 6 * rand5() + rand5();
-
如果 rand5() 范围 是 [ 0 ,1 ,2 ,3, 4],
那就相应 的为
i = 5 * rand5() + rand5();
第三种情况,n > m*m
先构建 第二种情况的函数,在利用上述函数,构建
更大范围的函数,再筛选