生成指定範圍內的隨機數,有相應的隨機函數(如RandomRange(x, y)
可生成x <= d < y
的隨機整數),或者在基本的隨機函數上稍加修改也可生成;生成 n 個隨機數,只需調用 n 次隨機函數便可;生成 n 個不重複的隨機數,就會有一點點小麻煩。算法
通常來講,要生成n個不重複的隨機數,只需判斷每次生成的隨機數有沒有和這前生成的隨機數重複便可,若重複即拋棄,不重複則記錄。數組
可是,這樣要進行不少額外的判斷,並且當生成的量變大時,這樣的判斷次數也幾乎是呈指數級的增長(具體複雜度沒有進行詳細分析)。dom
若是每生成一個隨機整數,就在一個整數序列上對應的位置作一個標記,那麼只須要判斷標記的個數有沒有達到n便可,而後把有標記的整數取出就是 n 個不重複的隨機整數。(其實該思路是借鑑了某個排序算法的思路,具體算法名稱不記得了)函數
首先來考慮生成 n 個[0, m)的不重複的隨機數方法,n < m
。code
var i: Integer; tmpMark: array of Integer; begin SetLength(tmpMark, m); repeat Randomize; i := RandomRange(0, m); //[0,m)半開半閉區間 tmpMark[i] := 1; until SumInt(tmpMark) = n; for i := 0 to m - 1 do if tmpMark[i] = 1 then i; //i即爲隨機出的不重複的整數 end;
本例中借滋長度爲m的數組tmpMark
來進行標記,同時使用delphi自帶的SumInt
(在Math單元)函數來計算標記的個數,有標記的tmpMark
下標即爲隨機出的整數。排序
對於[x, y)區間,能夠在[0, m)的基礎上進行平移來實現,n < y - x
。class
var l, i: Integer; tmpMark: array of Integer; begin l := y - x; SetLength(tmpMark, l); repeat Randomize; i := RandomRange(x, y); //[x,y)半開半閉區間 tmpMark[i - x] := 1; until SumInt(tmpMark) = n; for i := 0 to l - 1 do if tmpMark[i] = 1 then i + x; //i+x即爲隨機出的不重複的整數 end;