關於隨機數(不重複)
阿新 • • 發佈:2019-02-14
方法一
一般思路,大多數人也是網上比較多的:確定一個存一個。思路比較簡單,直接上摘過來的程式碼。
//網上方法獲取不重複隨機數 private static void testA(int sz){ long startTime=System.currentTimeMillis(); //開始測試時間 Random random = new Random(); int a[] = new int[sz];//隨機陣列 for (int i = 0; i < a.length; i++) { a[i] = random.nextInt(sz); for (int j = 0; j < i; j++) { while (a[i] == a[j]) {//如果重複,退回去重新生成隨機數 i--; } } } long endTime=System.currentTimeMillis(); //獲取結束時間 System.out.println("網上思路程式碼執行時間: "+(endTime-startTime)+"ms"); }
方法二
第一種方法一般很容易想到,然後我想了想還有沒有別的方法,一時間想不出來就去網上搜搜,結果大多數都是第一種,然後在一個網站上看到了一位寫了另一種方法,用到了集合。先上他的程式碼,網站在最後貼出來。
private static void testB(int sz){ long startTime=System.currentTimeMillis(); //開始測試時間 Random rd = new Random(); int[] rds = new int[sz];//隨機數陣列 int n = 0;//序號 List<Integer> lst = new ArrayList<Integer>();//存放有序數字集合 //獲取隨機數陣列, 裡面有重複數字 while (n < rds.length) { lst.add(n); rds[n++] = rd.nextInt(sz); } //把隨機數和有序集合進行匹對, 把隨機數在集合出現的數字從集合中移除掉. for (int i = 0; i < rds.length; i++) { for (int j = 0; j < lst.size(); j++) { if (rds[i] == lst.get(j)) { lst.remove(j); break; } } } //把陣列中重複的第二個數字用集合的第一個數字替換掉, 並移除掉陣列的第一個數字 for (int i = 0; i < rds.length; i++) { for (int j = 0; j < rds.length; j++) { if (i != j && rds[i] == rds[j]) { rds[j] = lst.get(0); lst.remove(0); break; } } } //得到的 rds 陣列就是不重複的隨機陣列 long endTime=System.currentTimeMillis(); //獲取結束時間 System.out.println("自定義程式碼執行時間: "+(endTime-startTime)+"ms"); }
第三種
按照他說的比第一種方法效能要好,尤其是在數越大的時候,這個我沒有測試。時我看完了還再想還有沒有其他方法,因為雖然效能好,但是程式碼量有點多了。結果昨天臨睡覺前想出來一個,很興奮,不過在今天下午就被澆了涼水。。。這是後話了。上個方法只是把有序的十個數打亂順序然後取出來,有時候可能需要在五十個數、一百個數、一千個數等等裡面取出若干的數,上面的方法可以再優化。再得到用集合的方法的啟發後,整體思路是:定義兩個變數來控制隨機數個數和隨機數取值範圍,動態定義隨機陣列,然後先用for迴圈將取值範圍按順序存入集合,也就是集合裡面的數就是可以取得的隨機數值。再用一個for迴圈來取十個數,迴圈內隨機一個範圍內的數作為下面集合裡的數值的下標,然後賦值給隨機陣列,再將這個值從集合中移除。在這裡用集合的好處體現出來了,當一個集合的一個元素被移除後,後面的會自動前移,即使下次隨機的下標和上一個一樣,得到的數值也不會重複。先上我自己寫出來的程式碼。
//count是要取的隨機數的個數,arround是隨機數在哪個範圍取 [0~arround)
public static int[] testA(int count, int arround){
long time = System.currentTimeMillis();//依舊是測試時間。。。
Random random = new Random();
ArrayList<Integer> numList = new ArrayList<>();//集合存放可以取的數值範圍
int[] rand = new int[count];//隨機陣列
for (int i = 1; i < arround+1; i++) {
numList.add(i);//迴圈把範圍內的數值順序放入結集合
}
for (int i = 0; i < count; i++) {
int n = random.nextInt(arround - i); // 隨機範圍內的數作為集合的下標
rand[i] = numList.get(n); //找到這下標的數值並賦值給隨機陣列
numList.remove(n);把該值從陣列移除
}
long time2 = System.currentTimeMillis();
System.out.println("testA執行時間: " + (time2 - time) + "ms");
return rand;
}
然後
悲劇來了!!
今天又去這個網站,然後看到了評論下面有個人也發了個方法,跟我這個差不多,但是有些一樣,去看過就知道了。啊啊啊啊,,,還以為發現了新大陸。。好吧,還是太年輕。。。隨機數應該還有別的方法吧,如果有人知道還望告知,謝謝!
不過思考了,就是值得的,畢竟也是靠自己(咳咳。。)寫出來的~加油~