天天看點

從M個數中随機等可能的取出N個的問題

從0到m-1這m個數中随機取出n個(n<=m) 要求每個數被取到的可能性相等。 

第一個方法是把這m個數丢到一個List裡面 然後用nextInt(list.size())來産生随機數 然後把list裡面對應的元素丢到另一個數組或者list裡面 這個方法本來是不錯的 但要注意的是 為了保證每個元素取到的機率相等 需要每取出一個元素 就把它從list裡面删除 原因就不解釋了 簡單的機率問題。但衆所周知的是 list的remove(int index)方法 效率并不高 尤其是當m和n很大的時候 每一次調用remove ArrayList都需要進行數組的copy 而LinkedList需要進行連結清單的周遊。 

是以再考慮這個問題,用數組來儲存這m個數是很好的 而且其實我們并不需要知道到底哪些下标的元素被選中了 第一個方法的效率低下的原因在于 nextInt(int i)這個方法是從0 到i-1随機生成整數 這裡要求0到i-1是連續的i個整數 而我們選取了一個數之後 為了滿足連續整數的條件 就要把這個數删去 而頻繁删除的效率是低下的 是以換一種思路 不采用删除 而采用交換 

第二個方法 比如0-99這100個數字 從小到大放在一個數組裡面 現在要選10個 我們隻需要随機打亂這個數組 然後選取前10個元素就好 随機打亂的方法就是 從數組頭元素開始 每次産生一個随機數n 然後交換這兩個數 而且隻需要交換十次就夠了 因為我們并不取下标超過10後面的數字 

繼續閱讀