2

我正在编写一个对数组中的项目进行洗牌的函数:

this.shuffle = function () {
    ...

首先,我得到数组的两半并设置第三个空数组:

    this.leftHalf = this.cards.slice(0, this.size() / 2);
    this.rightHalf = this.cards.slice(this.size() / 2);
    this.result = [];

接下来,我将每一半中的一张牌放入结果数组中:

    for (var i = ...) {
        this.result.unshift(this.leftHalf[i]);
        this.result.unshift(this.rightHalf[i]);
    }

最后,我将结果数组分配给我的原始数组并删除“临时”变量:

    this.cards = this.result;

    delete this.leftHalf;
    delete this.rightHalf;
    delete this.result;
}

我的问题:这是解决此问题的明智方法,还是有不涉及设置临时变量的更好方法?我考虑过使用私有变量(但不确定它是否会带来更好的性能),如下所示:

var leftHalf, rightHalf, result;

this.shuffle = function () {
    leftHalf = ...

只是好奇是否有任何明显的我做错了,或者在这些情况下是否有最佳实践。

4

3 回答 3

1

当我们说 Shuffle 这个词时,它必须是随机的。下面是我创建的一个片段,用于演示以随机方式重新排列 arral 值。

var shuffle = function() {

        var _deck = [ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M" ],
        _shuffle = [],
        _slice; 

        do {

           // return's a random index
           _splice = Math.floor( Math.random() * _deck.length );

           // store the random value in new array
           _shuffle.push( _deck[ _splice ] );

           // splice the random value
           _deck.splice( _splice, 1 );

        } while ( _deck.length );

    };

正如@hackartist 提到的,您可以阅读此http://blogs.discovermagazine.com/crux/2012/07/16/surprising-connection-between-card-shuffling-higgs-boson/并进一步扩展到 shuffle 方法以自行执行X 次

于 2012-08-23T09:38:52.597 回答
1

有很多很好的算法可以随机化一组元素的顺序。一个简单的方法是将最后一个元素与列表中的随机元素交换。然后将第 n-1 个元素与前 n-1 个元素中的随机一个交换(假设您的列表为 n 长),然后将第 n-2 个元素与前 n-2 个元素中的一个随机交换,等等。(注意你可以用它自己交换一个元素。)

天真的实现将使用一个临时变量,但有一些技巧可以使其完全到位。这些几乎从不需要,通常会降低可读性。

于 2012-07-29T20:56:25.220 回答
1

你可以在没有任何私有变量和一个循环的情况下做到这一点,尽管我怀疑会有很大的性能差异。假设您想要左手洗牌,因此顶部的牌在顶部,中间的牌在第二位,并且您的牌组的长度是偶数 N ...

for(var i=...) {
   if(i%2 == 1) 
      newdeck[i] = oldeck[N/2+(i-1)/2];
   if(i%2 == 0) 
      newdeck[i] = oldeck[i/2];
}

这将像您的原始算法一样完成所谓的完美洗牌,但正如人们所说,这不是随机的,因为它是可预测的。有一篇著名的论文说,要从一个有序的牌中找到一个看似随机的牌组,你需要运行 7 次完美的洗牌。如本文所述,您还可以使用左右洗牌来控制牌组中的牌。

于 2012-07-29T20:59:35.890 回答