2012-07-29 36 views
2

我正在寫一個數組打亂了項目的功能:在使用臨時變量的for循環

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

只是好奇,如果有什麼明顯的,我做錯了,或者如果有一個最佳實踐在這些情況下。

+1

的「臨時變量」您創建的性能自執行X號。如果你要刪除它們,只需使用'var'。我不會擔心表現,因爲那是他們的目標。 – Dennis 2012-07-29 20:54:44

+0

此外,您的shuffle算法具有高度的可預測性。我建議看看使用[真正的洗牌算法](https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle)。 – 2012-07-29 20:56:58

+0

@GregHewgill我認爲他想要一個完美的洗牌,因爲他從來沒有使用隨機任何字 – hackartist 2012-07-29 21:01:51

回答

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個完美的洗牌。您還可以使用右和左洗牌控制牌組中的牌,如this article

+0

爲什麼不使用'else'? – Prinzhorn 2012-07-29 21:01:13

+0

我只是認爲案件更清楚,但當然你可以使用其他案件。一種情況是偶數,另一種情況是奇數,但它們是互補的。 – hackartist 2012-07-29 21:02:33

+0

我認爲關於7次洗牌的說法是,你需要7次正常的淺灘洗牌(這是假設一張52張牌)以得到一個隨機表面甲板。經過7次完美的洗牌(半個交叉)之後,您將擁有很多結構。 – David 2012-07-29 21:15:40

1

有很多好的算法用於隨機化一組元素的順序。一個簡單的方法是將最後一個元素與列表中的隨機元素進行交換。然後將第n-1個元素與第一個n-1元素中的一個隨機交換(假設你的列表是n長),然後將第n-2個元素與第一個n-2元素中的一個隨機交換,等等。你可能會交換一個元素本身。)

這個天真的實現將使用一個臨時變量,但有一些技巧,使它完全到位。這些幾乎是不必要的,通常會降低可讀性。

+1

天真的實現將只是調用'.sort(function(){...})'在數組上,並使用'數學.random()'返回{-​​1,0,1} – Prinzhorn 2012-07-29 20:59:43

+0

之一但他不想隨機化他想做一個完美的洗牌,IE交錯卡 – hackartist 2012-07-29 21:00:13

+0

那麼,你是誰帶來了隨機化到討論;-) – Prinzhorn 2012-07-29 21:02:27

1

當我們說Shuffle一詞時,它必須是隨機的。以下是我創建的一個片段,用於以隨機方式重新排列阿拉爾數值。

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/並進一步延伸到洗牌法次