给定rand5()能随机生成整数1到5的函数,写出能随机生成整数1到7的函数rand7()

今天面试遇见的一道题,当时思路没完全跟上,回来查了下,Google的一道题;

参考 https://blog.csdn.net/hxz_qlh/article/details/12978771

分析: 思路:
很多人的第一反应是利用rand5() + rand5()%3来实现rand7()函数,这个方法确实可以产生1-7之间的随机数,但是仔细想想可以发现数字生成的概率是不相等的。rand()%3 产生0的概率是1/5,而产生1和2的概率都是2/5,所以这个方法产生6和7的概率大于产生5的概率。正确的方法是利用rand5()函数生成1-25之间的数字,然后将其中的1-21映射成1-7,丢弃22-25。例如两次rand5()分别生成(1,1),则看成rand7()中的2,如果出现22,23,24,25,则丢弃重新生成。

 

我的备注:
    这种思想是基于,rand()产生[0,N-1],把rand()视为N进制的一位数产生器,那么可以使用rand()*N+rand()来产生2位的N进制数,以此类推,可以产生3位,4位,5位...的N进制数。这种按构造N进制数的方式生成的随机数,必定能保证随机,而相反,借助其他方式来使用rand()产生随机数(如 rand5() + rand()%3 )都是不能保证概率平均的。

    Rand5产生1到5的数,减1就产生0到4的数,乘以5后可以产生的等概率数是:0,5,10,15,20。 再加上第二个Rand5()产生的1,2,3,4,5。我们可以得到1到25, 而且每个数都只由一种组合得到,即上述代码可以“等概率”地生成1到25。OK, 到这基本上也就解决了。
    此题中N为5,因此可以使用rand5()*5+rand5()来产生2位的5进制数,范围就是1到25。再去掉22-25,剩余的除3,以此作为rand7()的产生器。!

import random

# print(random.randint(0, 4))
# 给定rand5()能随机生成整数1到5的函数,写出能随机生成整数1到7的函数rand7()

def rand7():
    x = 0
    while True:
        x = 5 * (random.randint(1, 5) - 1) + random.randint(1, 5)
        if x > 21:
            continue
        else:
            return 1 + x % 7

sum_array = dict()

for i in range(500000):
    j = rand7()
    sum_array[j] = sum_array[j] + 1 if j in sum_array.keys() else 1


print(sum_array)

 

部分结果截屏,发现在大量数据模拟下,基本是平均的

 

$ python rand_5.py
{7: 71384, 6: 71395, 5: 71409, 4: 71340, 1: 71672, 2: 71258, 3: 71542}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值