Fisher-Yates算法解释?

时间:2015-06-27 14:42:24

标签: javascript arrays algorithm actionscript-3 shuffle

我想知道你们中的一些人是否理解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;
}
}

该代码完美无缺,但我仍然感到困惑

  1. 我将循环更改为" input.length"并且它不能很好地工作,我仍然得到了#34; 0"有时值。我不知道为什么要使用" input.length-1"而不是" input.length"
  2. 在随机化部分,我为什么要将索引从0随机化为值(i + 1),为什么我们不将它从0随机化为(i)呢?
  3. 如果你们中的一些人理解,你能解释一下吗? 非常感谢你

2 个答案:

答案 0 :(得分:0)

  1. Js的数组索引从0开始,因此长度为a的最后一个元素的数组na[n -1]

  2. 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]

的值