產生一組不重複隨機數的高效演算法
阿新 • • 發佈:2019-02-04
需要從 0 到 n 之間選 k 個不重複的陣列成一個序列。
最早我想的是用一個輔助陣列記錄之前已經產生的隨機數,如果當前產生的隨機數已經出現過就再重新隨機。
顯然這樣的實現效率是很低的,設想從10000個數中隨機產生10000個數的序列,當前面9999個數已經確定了時,最後一個數被隨機到的概率是 0.0001,也就是說大概需要呼叫隨機函式10000次才會產生。類似的,第9999個數被隨機到的概率是0.0002……
…..
那麼,高效的演算法來了
先上程式碼:
需求:從 0 到 n 之間選 k 個不重複的陣列成一個序列。
假設 n =4;k=4;(k<=n);
int n = 4;
int k = 4;
//生成0~n之間的陣列
int[] x = new int[n];
for (int i = 0; i < n; i++) {
x[i] = i;
}
//開始隨機 k 個不重複數出來
for (int i = 0; i < k; i++) {
Random random = new Random();
// t : i 至 n 的隨機數
// 目的:不再隨機出已置換出去 的數 的下標
int t = random.nextInt(n - i) + i;
// 交換x[i],x[t]的值
int temp = x[i];
x[i] = x[t];
x[t] = temp;
//此時輸出x[i]的值,就是第i 個隨機出的數。
System.out.println("隨機數== " + x[i]);
}
文采不好,直接進入靈魂畫師環節。。。。
再來一段小描述:
首先,x數組裡把0到n-1的所有數都儲存了,而最後輸出的都是x數組裡的值,所以滿足輸出的數是k個0到n-1的數。
然後,我們對於第 i 次隨機,產生一個 i 到 n-1 的下標 t ,並把x[t] 和x[i]交換,將其輸出,這樣每次產生的數都是之前沒有出現過的數,因為之前出現過的數都在x[0] 到 x[i-1]裡呢!這樣就保證了輸出資料的不重複性。
可以了吧!
關注微信公眾號,長期乾貨分享