算法导论5.1-1
参考博客
http://blog.youkuaiyun.com/effenberg11/article/details/5976838
http://qianggezhishen.bokee.com/viewdiary.43964492.html
博客中算法
1、把要生成的数标记为 a, a+1, a+2,..., b-a+1,…,b-1,b
2、取最小的 m,使得 2^m >= n
3、通过随机生成 0,1 的函数生成一个 m 比特整数(随机生成每一位),这样能随机生成 [a, 2^m) 内的整数。
4、随机生成一个 [a,2^m) 中的整数,如果这个数大小在 [a, b] 内,则取这个数为结果。如果这个数在 [a, b] 外,则丢弃它,重新生成一个。
看着有点绕。重写一下。。
1、通过Random(0,1)生成Random(a,b),实际上我们生成random(0,b-a)+a 就可以了,然后问题就转换为了Random(0,1)生成Random(0,n), 这里n=b-a
2、由于n可能不是2的整数幂,要找到最小的m使 2^m >n
int getM(int n)
{
m =0;
while(n>=2)
{
n=n/2;
m++;
}
if(pow(2,m)<n)
m++;
return m;
}
然后生成随机数0~2^m,可以分治法递归也可以二进制按位计算(推荐),如果随机数result落在0~n之间,则随机数生成成功,如果随机数落在n+1~2^m,则重新生成随机数。一次成功生成随即书的概率为n/2^m。令p=n/2^m所以时间复杂度o=p+p(1-p)*2+p(1-p)^2*3+....+np(1-p)^(n-1)=1/(1-p) (等比数列相关问题,高中数学加一点极限问题,不解释)
上述可能计算有误,思想应该是没问题的~~