我想知道你们中的一些人是否理解Fisher-Yates洗牌是如何工作的,并且可以向我解释。所以我在网上发现了这个Fisher-Yates Shuffle代码:
public function Main() {
var tempArray:Array = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
ShuffleArray(tempArray);
trace(tempArray);
}
public function ShuffleArray(input:Array)
{
for (var i:int = input.length-1; i >=0; i--)
{
var randomIndex:int = Math.floor(Math.random()*(i+1));
var itemAtIndex:Object = input[randomIndex];
input[randomIndex] = input[i];
input[i] = itemAtIndex;
}
}
该代码完美无缺,但我仍然感到困惑
如果你们中的一些人理解,你能解释一下吗? 非常感谢你
答案 0 :(得分:0)
Js的数组索引从0开始,因此长度为a
的最后一个元素的数组n
为a[n -1]
。
Math.random返回一个从0到0.9999 ....的值,但不包括1(范围为[0, 1)
),因此Math.random()* (i + 1)
将具有{{1的值} 0
,而不是i + 0.999999......
(范围i + 1
),并使用[0, i+1)
剪切点部分以获得Math.floor
,因此我们得到了范围Integer
中的数字。
答案 1 :(得分:0)
让我用一个带有否定的例子来解释,让我们说数组大小是10。
1)如果我们在for循环中使用index.length第3行将读取
input[randomIndex] = input[i] i.e.
input[randomIndex] = input[10];
但由于javascript有0个基于数组,因此它具有从索引0到9的值。指数10将超出界限。我们应该从最后一个元素(仅限索引9)进行随机播放
2)对于你的第二个问题,如果我们使用i而不是i + 1。 假设您处于索引9的循环的第一次迭代中(对于其他迭代也将保持为真)。 在这里我是9,如上所示。我们希望第9个索引从0到9中的任何一个索引洗牌 Math.random将从0返回到.999并且Math.floor将降低它的约束,因此在我们的情况下,最大值将为.999 *(9 + 1)= 9.99 .Math.floor将其下限限制为9.So范围是[0,9]
如果我们使用i,则最大可能值为8,即范围[0,8]
因此我们使用i + 1,因为我们需要来自[0,9]
的值