470. 用 Rand7() 实现 Rand10() (拒绝采样+进制转换)

在这里插入图片描述

解法:拒绝采样 + 进制转换

思路:在拒绝采样中,如果生成的随机数满足要求,那么就返回该随机数,否则会不断生成,直到生成一个满足要求的随机数为止。
我们只需要能够满足等概率的生成 10个不同的数即可,具体的生成方法可以有很多种。
自古评论区出人才:
通过两次独立的随机过程,生成两个随机数a和b,将其看做两个7进制数,它们一共可以表示0~48范围内的数,这49个数中每个数的生成概率都是相等的,取前10个就可以满足要求。

// The rand7() API is already defined for you.
// int rand7();
// @return a random integer in the range 1 to 7

int rand10() {
    int ret;
    for(;;)
    {
        // a和b独立
        int a = rand7()-1;
        int b = rand7()-1;
        // 两位7进制数ab,转10进制
        ret = a*7+b; 
        // 只取前10个数
        if(ret < 10 ) break;
    }
    ret = ret + 1;
    return ret;
}

进阶:怎么少调用rand7()?
现在只有1049\frac{10}{49}4910的概率生成我们需要的数,现在想办法让更多的数被我们用到。
可以取前40个数。就有4049\frac{40}{49}4940的概率能产生符合要求的随机数。

// The rand7() API is already defined for you.
// int rand7();
// @return a random integer in the range 1 to 7

int rand10() {
    int ret;
    for(;;)
    {
        // a和b独立
        int a = rand7()-1;
        int b = rand7()-1;
        // 两位7进制数ab,转10进制
        ret = a*7+b; 
        // 只取前40个数
        if(ret < 40 ) break;
    }
    ret = ret/4 + 1;
    return ret;
}

rand7()调用次数的期望值?
调用两次rand7(),成功的概率是4049\frac{40}{49}4940。rand7()调用次数的期望:
14049∗2=2.45\frac{1}{\frac{40}{49}}*2=2.45494012=2.45

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值