Javascript Fisher-Yates算法解释?
我想知道你们中的一些人是否了解费舍尔·耶茨洗牌的工作原理,并能向我解释一下。我在网上找到了Fisher-Yates的洗牌代码:Javascript Fisher-Yates算法解释?,javascript,arrays,actionscript-3,shuffle,fisher-yates-shuffle,Javascript,Arrays,Actionscript 3,Shuffle,Fisher Yates Shuffle,我想知道你们中的一些人是否了解费舍尔·耶茨洗牌的工作原理,并能向我解释一下。我在网上找到了Fisher-Yates的洗牌代码: 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 =
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;
}
}
那个代码工作得很好,但我还是很困惑
n
的数组a
的最后一个元素是a[n-1]
[0,1)
),因此Math.random()*(i+1)
,将有一个介于0
到i+0.9999之间的值……
,但不包括i+1
(范围为[0,i+1)
),并使用Math.floor
剪切点部分,得到一个整数,因此我们得到一个范围[0,i]
内的数字
让我用一个否定的例子来解释,让我们说数组大小是10 1) 如果我们使用index.length,for循环中的第3行将读取
input[randomIndex] = input[i] i.e.
input[randomIndex] = input[10];
但由于javascript有基于0的数组,它的值从索引0到9。索引10将超出范围。因此我们应该从最后一个元素(仅索引9)开始洗牌
2) 对于你的第二个问题,如果我们用i代替i+1。
假设您处于索引9的循环的第一次迭代中(对于其他迭代也将保持true)。
这里我是9,如上所示。我们希望第9个索引从0到9的任何一个索引中洗牌
Math.random将从0返回到.999,Math.floor将对其进行下界,因此在我们的例子中,最大值将为.999*(9+1)=9.99。Math.floor将把其下界为9。因此范围为[0,9]
如果我们使用i,则最大可能值为8,即范围[0,8]
因此,我们使用i+1,因为我们需要[0,9]的值。您应该使用
长度-1
,因为数组是零基的,第一项是[0]
,但长度是项目的计数,从1
Ahh开始,我明白了。为什么我要将索引从0随机化到(i+1),而不是从0随机化到(i)它只是得到一个随机数,所以它是Math.random()*(i+1)
而i+1
部分主要是在第一次迭代时不得到Math.random()*0
,这将是0
,但是在用长度-1声明它之后,“i”值将是=“9”对吗?如果我使用Math.random()*(i),它将是Math.random()*(9) 我不会得到“0”值。如果使用Math.random()*(I+1),它将是Math.random()*(10),我也不会得到“0”。所以..我认为如果我使用Math.random*(I)而不是Math.random*(I+1),不会有任何区别吗??