所以这是一个面试问题。
为您提供了一个函数rand5()
,该函数生成范围为[0-5]的随机整数,即{0,1,2,3,4,5}
a)您可以使用该函数生成范围为[0-7]的随机整数吗?
b)您可以使用该函数生成范围为[0-7]的随机整数,每个数字具有相等的概率吗?
您可以多次使用该功能。
a部分((rand5() +rand5())*7)//10
的一种解决方案,其中// represents integer division
的范围为[0-7],但是概率不相等。
很乐意看到您对此的答案和思考过程。
答案 0 :(得分:5)
$one = rand5();
$two = rand5();
$four = rand5();
return (($four < 3)? 4 : 0) + (($two < 3)? 2 : 0) + ($one < 3)? 1 : 0);
答案 1 :(得分:2)
尝试这种方法:
因此 rand7()可以是:
// returns random number between 0-5 with equal probability
function rand5() {
return Math.floor(Math.random() * 6);
}
// returns random number between 0-7 with equal probability
function rand7() {
if(rand5() % 2 == 0 && rand5() % 2 == 0) {
return 6 + rand5() % 2;
} else {
return rand5();
}
}
console.log(rand7());
答案 2 :(得分:0)
骰子有相等的机会掷出任何一面。如果所需的范围小于骰子的范围,只需在超出范围时重新滚动即可。
当所需范围大于一个芯片的范围时,就会出现问题。多个骰子掷骰的总和不是正态分布的,因此增加多个掷骰子的值是行不通的。
相反,请考虑使用连续滚动来逐步“放大”子范围内的值。如果我们滚动一个6面的模具两次,则第一次滚动将选择一个6个单位的子范围,例如12-17(包括12-17)。第二轮将从该子范围中选择一个值,例如14。
同样,与单个骰子一样,如果范围大于期望值,则只需拒绝超出范围的值,然后再次滚动。
答案 3 :(得分:0)
这可以使用Rejection Sampling完成。
考虑将卷布置在如下所示的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]
现在,如果您滚动模具两次,则可以在2D网格中生成任何位置(第一行表示行位置,第二行表示列位置)。共有36
个职位。由于我们要生成[0, 7]
范围内的数字,因此我们需要输出空间为8
的倍数。如果我们考虑第一个32
位置(按主要顺序排列),我们可以将它们分成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;
}
}
}