给定一个随机数生成器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

先构建 第二种情况的函数,在利用上述函数,构建

更大范围的函数,再筛选

原文地址:https://www.cnblogs.com/gaoyang666/p/12455744.html