现在有一个函数rand(0,1)可以随机生成0或者1,即生成0的概率是1/2,生成1的概率也是1/2.现在要求用这个函数实现函数rand(a,b):生成a和b之间的随机数(包含a和b),并分析时间复杂度~
取值c = b-a作为一个整数,找到不小于数c的第一个2的n次方(例如,如果c为5,就是2的3次方是8;c为63就是2的6次方64) 之后利用rand(0,1),分别每次产生这个2^n的数的每一位,这样的方法可以随机的保证在0-2^n-1以等概率产生随机数,如果产生的这个数randNum在[0,c]的范围内,返回a+randNum;如果产生的数在(c,2^n)之间,则重新生成一个随机数直到落入[0,c]的范围。
一般是已知一个生成1-m随机数的函数rand(1, m),要求一个生成1-n随机数的函数rand(1, n),n往往与m互质,一般的做法是先将rand(1, m)扩大为一个生成1-m^k随机数的函数rand(1, m^k),使得m^k >= n,然后再调用函数rand(1, m^k)。如果其生成的数在[1 n]之间,直接返回作为结果,如果其生成的数在(n, m^k], 那么就进入一个反复调用rand(1, m^k)的循环,直到取得的随机数落在[1 n]为止。该算法在最差情况下的时间复杂度为无穷大,但其最差情况发生的概率也是极其小的。
- rand(1, m^k)
- {
- //调用rand(1, m)达到目的
- return result // 位于[1, m^k]之间
- }
-
- rand(1, n)
- {
- do
- {
- result = rand(1, m^k);
- }
- until (result in range[1, n])
- return result;
- }