其他题目---从5随机到7随机及其扩展

【题目】

  给定一个等概率产生1~5的随机函数 rand1To5如下:

def rand1To5():
    return int(random.random()*5) + 1

  除此之外,不使用任何额外的随机机制,请用rand1To5实现等概率随机产生1~7的随机函数rand1To7。

【补充题目】

  给定一个以p概率产生0,以1-p概率产生1的随机函数rand01p如下:

def rand01p():
    p = 0.83  #p可以随意改变
    return 0 if random.random() < p else 1

  除此之外,不使用任何额外的随机机制,请用rand01p实现等概率随机产生1~6的随机函数rand1To6。

【进阶题目】

  给定一个等概率随机产生1~M的随机函数rand1ToM如下:

def rand1ToM(m):
    return int(random.random() * m) + 1

  除此之外,不能使用任何额外的随机机制。有两个输入参数,分别为m和n,请用rand1ToM(m)实现等概率随机产生1~n的随机函数rand1ToN。

【基本思路】

  原问题。
  1、rand1To5() 等概率产生1,2,3,4,5
  2、rand1To5()-1 等概率产生0,1,2,3,4
  3、(rand1To5()-1)*5 等概率的产生0,5,10,15,20
  4、(rand1To5()-1)*5+rand1To5()-1 等概率的产生0,1,2,3…23,24
  5、如果步骤4产生的结果大于20,重新随机,直到产生的结果在0~20之间。
  6、步骤5的结果再进行%7,然后再加1,就是最终的结果。

#python3.5
def rand1To5():
    return int(random.random()*5) + 1

def rand1To7():
    num = (rand1To5()-1) * 5 + rand1To5() - 1
    while num > 20:
        num = (rand1To5()-1) * 5 + rand1To5() - 1
    return num % 7 + 1

  补充题目。
  虽然rand01p方法是以p的概率产生0,以1-p的概率产生1,但是rand01p产生01和10的概率却都是p(1-p),可以利用这点来实现等概率随机产生0和1的函数。

def rand01():
    num = rand01p()
    while num == rand01p():
        num = rand01p()
    return num

  有了等概率产生0和1的函数,接下来的步骤和原问题类似。先实现随机产生0~3的随机函数,再利用0~3的随机函数实现随机产生1~6的随机函数。

def rand01p():
    p = 0.83
    return 0 if random.random() < p else 1

def rand01():
    num = rand01p()
    while num == rand01p():
        num = rand01p()
    return num

def rand0To3():
    return rand01()*2 + rand01()

def rand1To6():
    num = rand0To3() * 4 + rand0To3()
    while num > 11:
        num = rand0To3() * + rand0To3()
    return num % 6 + 1

  进阶题目。
  1、将n-1转换成m进制数,假设结果转换成数组为 k = [a,b,c,d,e]
  2、使用rand1ToM(m)函数产生结果数组 res = [A,B,C,D,E],如果res所表示的数值大于k所表示的数值,将res丢掉重新随机,直到产生的结果小于或等于k,这时产生的res的范围就在0~n-1之间,但是此时res所表示的数还是m进制的。
  3、将res数组转换成10进制整数。
  4、将步骤3的结果加1就是最终的结果。

def rand1ToM(m):
    return int(random.random() * m) + 1

def rand1ToN(n, m):
    def getMSysNum(value, m):
        res = []
        while value != 0:
            res.append(value % m)
            value //= m
        return res[::-1]

    def getRandMSysNumLessN(nMSys, m):
        res = []
        lastEqual = True
        index = 0
        while index < len(nMSys):
            res.append(rand1ToM(m) - 1)
            if lastEqual:
                if res[-1] > nMSys[index]:
                    index = 0
                    res = []
                    continue
                else:
                    lastEqual = True if res[-1] == nMSys[index] else False
            index += 1
        return res

    def getNumFromMSysNum(mSysNum, m):
        res = 0
        for i in range(len(mSysNum)):
            res = res * m + mSysNum[i]
        return res

    nMSys = getMSysNum(n-1, m)
    randNum = getRandMSysNumLessN(nMSys, m)
    return getNumFromMSysNum(randNum, m) + 1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值