JavaScript隨機打亂數組元素的位置(洗牌演算法)

來源:互聯網
上載者:User

[javascript] 
function mess(arr){ 
    var _floor = Math.floor, _random = Math.random, 
        len = arr.length, i, j, arri, 
        n = _floor(len/2)+1; 
    while( n-- ){ 
        i = _floor(_random()*len); 
        j = _floor(_random()*len); 
        if( i!==j ){ 
            arri = arr[i]; 
            arr[i] = arr[j]; 
            arr[j] = arri; 
        } 
    } 
    return arr; 

var testa = [1, 2, 3, 4, 5, 6, 7]; 
mess(testa); 
console.log(testa); 
要注意一點的是,這是改變原數組的,不想改變原數組的話請先拷貝原數組:

[javascript] 
var testa = [1, 2, 3, 4, 5, 6, 7]; 
var newarr = mess( testa.slice(0) ); //這裡只是淺拷貝數組 
console.log(testa); 
console.log(newarr); 
這個洗牌函數算好嗎?
呵呵,或許經過測試你會發現:有一些元素在洗完牌後位置依然是原來的位置,而且出現這種元素的幾率很大。那怎麼改進呢?

在現實當中,我們洗完牌後,通常還會把撲克一分為二(俗稱“切牌”),然後交換這兩部分的上下位置。嗯,對,這個洗牌函數裡我們沒有切牌!

所以我們可以做如下改進:

[javascript] 
//洗牌演算法 
function mess(arr){ 
    var _floor = Math.floor, _random = Math.random, 
        len = arr.length, i, j, arri, 
        n = _floor(len/2)+1; 
    while( n-- ){ 
        i = _floor(_random()*len); 
        j = _floor(_random()*len); 
        if( i!==j ){ 
            arri = arr[i]; 
            arr[i] = arr[j]; 
            arr[j] = arri; 
        } 
    } 
    //增加切牌操作 
    i = _floor(_random()*len); 
    arr.push.apply(arr, arr.splice(0,i)); 
    //return arr; //要不要返回打亂後的數組呢? 

var testa = [1, 2, 3, 4, 5, 6, 7, 8, 9]; 
var newarr = testa.slice(0); 
mess(newarr); 
console.log(testa); 
console.log(newarr); 
好,現在看來,已經很少出現洗牌前後位置不變的元素了,可以說大功告成了。
巴特,稍等,我們已經發現,這個洗牌函數是會改變原始數組的,那麼,接下來有一個問題:這個函數要不要傳回值,返回打亂後的數組?因為我可能想這麼來調用它:
[javascript]  
var testa = [1, 2, 3, 4, 5, 6, 7]; 
var newarr = mess( testa.slice(0) ); //這裡只是淺拷貝數組 
這種調用方式好嗎?如果加上這種調用方式,那麼可以算一共有兩種調用方式。
其實,對這麼一個簡單函數而言,調用方法應該越簡單越好,簡單易用,最好只提供一種調用方式。使用方法多了就需要人多記東西,容易讓人迷糊。所以,我不想給這個洗牌函數傳回值,不想提供這種調用方式。
而且還有一個原因:這有利於強調這是一個改變原數組的函數,而不是通過傳回值來給出調用結果,這樣可以讓調用者明確知道調用函數的影響。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.