Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/476.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Fisher-Yates算法解释?_Javascript_Arrays_Actionscript 3_Shuffle_Fisher Yates Shuffle - Fatal编程技术网

Javascript 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 =

我想知道你们中的一些人是否了解费舍尔·耶茨洗牌的工作原理,并能向我解释一下。我在网上找到了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 = 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;
}
}
那个代码工作得很好,但我还是很困惑

  • 我将循环更改为“input.length”,但效果不好,有时仍然得到“0”值。我不知道为什么我应该使用“input.length-1”而不是“input.length”
  • 在“随机化”部分,为什么我要将索引从0随机化为值(I+1),为什么我们不将其从0随机化为(I)
  • 如果你们中的一些人理解它,你能给我解释一下吗? 多谢各位

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

  • Math.random返回一个介于0到0.9999之间的值,但不包括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),不会有任何区别吗??