[JAVA] - 高效的從 m 個元素中隨機選中 n 個

來源:互聯網
上載者:User

標籤:copy   oms   yate   複製   元素   去重   class   arrays   post   

之前業務中曾經遇到過從m個元素中選取 n 個的需求,當時只是跑迴圈根據長度進行隨機選取,然後放入 Set 中去重,一直到收集到足夠的個數。

這樣做的缺點很明顯,當剩下的元素個數越少的時候,選取的元素越容易重複,並且,使用 Set 去重,值相同的字串會被認為是相同的元素,即使給入的數組確實有重複的資料。

直到最近看到了 Fisher-Yates 洗牌演算法,從中收到啟發,寫了一個從 m 個元素中選取 n 個的方法,該方法效能上有了很大提升,並且可以保證取到的元素的索引絕對不會重複。如果數組中的確有相同的元素,也不會影響到被選取的機率。

 1     public static <T> T[] randomSelected(T[] array, int num) { 2         T[] temp = Arrays.copyOf(array, array.length);   // 獲得一個該數組的複製 3         int length = temp.length; 4         int left = length; 5         while (length - left < num) {  // length - left 為還需要計算多少次 6             int i = (int) Math.floor(Math.random() * left--);  // 隨機選取一個元素,left 自減,這樣不會覆蓋上次產生的結果,並將下次選取的範圍縮小 7             T tmp = temp[i];  // 將被選中的數與數組的最後一位進行調換 8             temp[i] = temp[left]; 9             temp[left] = tmp;10         }11         return Arrays.copyOfRange(temp, 0, num > length ? length : num);  // 從臨時數組中複製出指定長度的數組12     }

該演算法不僅速度快,而且索引絕對不會重複!(如果數組裡面有重複的元素,我認為這是你想要的結果,畢竟去重不是一件難事)

如果 傳入的 num 等於數組的長度,還可以得到一個被打亂了順序的數組!

 

[JAVA] - 高效的從 m 個元素中隨機選中 n 個

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.