如何高效產生多個不重復的隨機數
類型一: 完全范圍內的隨機數
- 舉例: 在整數1-100以內, 產生100個不同的隨機整數
- 思想: 將所有數字打亂, 按順序選取各個數
1 int a[100]; 2 3 //1.初始化:按序列號依次賦值 4 for(int i=0; i<=99; ++i) 5 { 6 a[i]=i; 7 } 8 //2.生成不同的隨機數序列 9 for(int i=99; i>=1; --i) 10 { 11 swap(a[i], a[rand()%i]); 12 }
上面這段代碼只需要遍歷一次就可以產生這100個不重復的隨機數.
類型二: 部分范圍內的多個不同的隨機數
- 舉例: 在整數1-100以內, 產生20個不同的隨機整數
- 思想: 標記無沖突法
1 void GenerateDiffNumber(int *diff,int maxn,int num) 2 { 3 int rnd; 4 int *tmp; 5 tmp = (int *)malloc(sizeof(int)*maxn); 6 7 //1.初始化 8 for (int i = 0; i < maxn; i++) 9 { 10 tmp[i] = i; 11 } 12 13 //2.產生num個不同的數 14 for (int i = 0; i < num; i++) 15 { 16 do 17 { 18 rnd = rand() % maxn;//rnd<maxn 19 20 } while (tmp[rnd]==-1); 21 22 diff[i] = rnd; 23 tmp[rnd] = -1; //該位置的數已被選擇過,將其標記為-1 24 } 25 26 free(tmp); 27 }
這段代碼也是隨機產生位置,但它預先把整個數組初始化為位置序號,然后隨機產生其中一個位置,如果該元素
值不為-1,表示這個位置還沒有被使用過,就把i賦予它;否則,就重新隨機產生另一個位置,直到整個數組
被填滿。這個方法,越到后面,遇到已使用過的元素的可能性越高,重復次數就越多,這是不及第一個方
法的地方,但總的來說,效率還是不錯的。