Algorithm 给定一个随机整数生成器[0-5],生成[0-7]

Algorithm 给定一个随机整数生成器[0-5],生成[0-7],algorithm,Algorithm,这是一个面试问题 我们为您提供了一个函数rand5(),该函数生成范围为[0-5]的随机整数,即{0,1,2,3,4,5} a) 您可以使用该函数生成[0-7]范围内的随机整数吗 b) 你能用这个函数生成一个[0-7]范围内的随机整数,每个数字的概率相等吗 您可以多次使用该功能 a部分的解决方案之一,((rand5()+rand5())*7)//10其中//表示整数除法将给出范围[0-7],但概率不相等 希望看到您的答案和思考过程。$one=rand5(); $one = rand5(

这是一个面试问题

我们为您提供了一个函数
rand5()
,该函数生成范围为[0-5]的随机整数,即{0,1,2,3,4,5}

a) 您可以使用该函数生成[0-7]范围内的随机整数吗

b) 你能用这个函数生成一个[0-7]范围内的随机整数,每个数字的概率相等吗

您可以多次使用该功能

a部分的解决方案之一,
((rand5()+rand5())*7)//10
其中
//表示整数除法
将给出范围[0-7],但概率不相等

希望看到您的答案和思考过程。

$one=rand5();
    $one  = rand5();
    $two  = rand5();
    $four = rand5();

    return (($four < 3)? 4 : 0)  +  (($two < 3)? 2 : 0)  +  ($one < 3)? 1 : 0);
$two=rand5(); $4=rand5(); 回报率($4<3)?4:0)+($2<3)?2:0)+($1<3)?1 : 0);
模具在任何一侧滚动的机会均等。如果所需的范围小于模具的范围,只要在超出范围时重新滚动即可

当所需范围大于一个模具的范围时,问题就会出现。多个骰子掷骰的总和不是完全正态分布,因此将多个骰子掷骰的值相加将不起作用

相反,可以考虑使用连续滚动来逐步“放大”子范围内的值。如果我们滚动一个6面模具两次,第一次滚动将选择一个6单位的子范围,例如,12–17,包括在内。第二次滚动将从该子范围中选择一个值,如14

同样,与单个模具一样,如果范围大于所需范围,只需拒绝超出范围的值,然后再次滚动。

这可以使用。
int rand7() {
    while(true) {
        int row = rand(5);
        int col = rand(5);
        int pos = row * 6 + col;
        if(pos < 32) {
            return pos/4;
        }
    }
}
考虑在下面的<2/P > 2D网格中排列的辊
[0, 1, 2, 3, 4, 5]
[0, 1, 2, 3, 4, 5]
[0, 1, 2, 3, 4, 5]
[0, 1, 2, 3, 4, 5]
[0, 1, 2, 3, 4, 5]
[0, 1, 2, 3, 4, 5]
现在,如果您滚动模具两次,您可以在二维网格中生成任何位置(第一行表示行位置,第二行表示列位置)。总共有36个职位。因为我们想在
[0,7]
范围内生成数字,所以我们需要输出空间是
8
的倍数。如果我们首先考虑代码>32 < /COD>位置(以一行为主的顺序),我们可以将它们拆分为<代码> 4 < /代码>索引组。比如说

[0, 1, 2, 3] in first row => 0
[4, 5, 0, 1] in first and second row => 1
[2, 3, 4, 5] in second row => 2
...
[4, 5, 0, 1] in fifth and sixth row => 7
如果我们最后滚动
4个位置,我们将再次滚动

int rand7() {
    while(true) {
        int row = rand(5);
        int col = rand(5);
        int pos = row * 6 + col;
        if(pos < 32) {
            return pos/4;
        }
    }
}
int rand7(){
while(true){
int row=兰特(5);
int col=兰特(5);
int pos=行*6+列;
如果(位置<32){
返回pos/4;
}
}
}
尝试以下方法:

  • rand5()以相等的概率生成0-5之间的随机数。另外,rand5()返回的三个数字(0、2、4)是偶数,其他三个(1、3、5)是奇数。因此,它以相等的概率产生偶数和奇数
  • 如果rand7()以相等的概率返回所有数字,则rand7()中6的概率应为1/8。另外,rand5()三次返回偶数的概率为1/8
因此,rand7()可以是:

//以相等的概率返回0-5之间的随机数
函数rand5(){
返回Math.floor(Math.random()*6);
}
//以相等的概率返回0-7之间的随机数
函数rand7(){
如果(rand5()%2==0&&rand5()%2==0){
返回6+5()%2;
}否则{
返回rand5();
}
}

log(rand7())你能修改这个方法来使用吗,比如说9而不是7?很好的方法,尽管它不应该是
=3
?(所以0,1,2是0,3,4,5是1)。也许值得注意的是,只要源随机函数产生偶数个值,并且所需的范围是从零到二减一的幂次方,这种方法就会起作用。@erickson是的,但我们这里没有0/1硬币,而是rand5()给出的结果是0..5,(4或5)的概率是1/3。另外,我应该写“用这种方法得到7的概率”@MBo啊,对。我的评论是基于这样一个假设,即他会像上面提到的那样修复这个bug。人们正在对此进行投票,但书面上并没有给出统一的分布。也,如果目标结果数不是2的幂,这种方法将不起作用——在这种情况下,你需要一个拒绝方案。我认为可能重复的问题会被标记为重复问题,前提是重复的问题有一个可接受的答案。@erickson我研究了一点,没有找到答案支持我的声明的策略或元帖子。我可能在什么地方看到过这样的评论。此外,我总是假设在接近“这个问题已经有了答案……”的效果后,重复的问题措辞等同于“有了答案”和有了一个可接受的答案。不过,我想这更微妙。有一个类似的答案,超过550票赞成。