方案一、無序不重復(fù)數(shù)列
通過無序數(shù)列代替隨機數(shù)俏竞,如:[7, 2, 8, 4, 9, 0]
現(xiàn)在我們模擬一個隨機數(shù)范圍在 [0,4] 的序列
①首先,初始化一個順序數(shù)組,數(shù)組大小等于所需最大隨機數(shù) #Seq:【0分井,1,2歼疮,3杂抽,4】
②以 5 為基數(shù)隨機一個下標(biāo) # i = 3
③取i=3的值 3 ,得數(shù)組 out:【3】
④在Seq序列中移除seq[3]韩脏,得數(shù)組Seq:【0,1,2,4】
⑤循環(huán)②③④ 得最終序列out:【3, 4, 0, 1, 2】
Tip:
當(dāng)數(shù)組中remove一個值時缩麸,該下標(biāo)之后的所有值都往前挪動一位,因此赡矢,當(dāng)數(shù)組較大時杭朱,耗時會很大,嚴重印象效率
優(yōu)化
在④中吹散,不再直接remove seq[i]弧械,改為將seq[i]與seq[end]互換,即此時序列為 Seq:【0,1,2,4,3】空民;
而后刃唐,在②中,不再以 5 為基數(shù)隨機界轩,改為length-1 = 4画饥,即默認移除了最后一位seq[end] ,Seq:【0,1,2,4】
這樣就只需要做一次互換處理浊猾,不需要對 i 之后的所有值全體向前挪動一位
最終代碼
/**
* 無序不重復(fù)數(shù)列
* @param maxNum 數(shù)值范圍
* @param total 數(shù)列大小
* @return 隨機序列
*/
private int[] getNoDuplicatesRandom(int maxNum, int total) {
int[] sequence = new int[maxNum];
int[] output = new int[total];
for (int i = 0; i < maxNum; ++ i) {
sequence[i] = i;
}
int position;
Random random = new Random();
for (int i = 0; i < total; ++ i) {
// System.out.println("sequence: " + Arrays.toString(sequence));
position = random.nextInt(maxNum)%maxNum;
// System.out.println("position: " + position);
output[i] = sequence[position];
// System.out.println("output: " + Arrays.toString(output));
sequence[position] = sequence[--maxNum];
}
return output;
}
以下為對[0.10)取最多6位隨機數(shù)的結(jié)果
sequence: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
position: 7
output: [7, 0, 0, 0, 0, 0]
sequence: [0, 1, 2, 3, 4, 5, 6, 9, 8, 9]
position: 2
output: [7, 2, 0, 0, 0, 0]
sequence: [0, 1, 8, 3, 4, 5, 6, 9, 8, 9]
position: 2
output: [7, 2, 8, 0, 0, 0]
sequence: [0, 1, 9, 3, 4, 5, 6, 9, 8, 9]
position: 4
output: [7, 2, 8, 4, 0, 0]
sequence: [0, 1, 9, 3, 6, 5, 6, 9, 8, 9]
position: 2
output: [7, 2, 8, 4, 9, 0]
sequence: [0, 1, 5, 3, 6, 5, 6, 9, 8, 9]
position: 0
output: [7, 2, 8, 4, 9, 0]