C# Random 生成不重複随機數
Random 類 命名空間:System 表示僞随機數生成器,一種能夠産生滿足某些随機性統計要求的數字序列的裝置。 僞随機數是以相同的機率從一組有限的數字中選取的。所選數字并不具有完全的随機性,因為它們是用一種确定的數學算法選擇的,但是從實用的角度而言,其随機程度已足夠了。 僞随機數的生成是從種子值開始。如果反複使用同一個種子,就會生成相同的數字系列。産生不同序列的一種方法是使種子值與時間相關,進而對于 Random 的每個新執行個體,都會産生不同的系列。預設情況下,Random 類的無參數構造函數使用系統時鐘生成其種子值,而參數化構造函數可根據目前時間的計時周期數采用 Int32 值。但是,因為時鐘的分辨率有限,是以,如果使用無參數構造函數連續建立不同的 Random 對象,就會建立生成相同随機數序列的随機數生成器。 通過建立單個而不是多個 Random 對象可以避免此問題。 若要提高性能,請建立一個随時間推移能生成多個随機數的 Random 對象,而不要反複建立會生成同一個随機數的 Random 對象。 Random 成員 名稱 ● 說明 Equals ● 确定指定的 Object 是否等于目前的 Object。(繼承自 Object。) Finalize ● 允許 Object 在“垃圾回收”回收 Object 之前嘗試釋放資源并執行其他清理操作。(繼承自 Object。) GetHashCode ● 用作特定類型的哈希函數。(繼承自 Object。) GetType ● 擷取目前執行個體的 Type。(繼承自 Object。) MemberwiseClone ● 建立目前 Object 的淺表副本。(繼承自 Object。) Next ● 已重載。 傳回随機數。 NextBytes ● 用随機數填充指定位元組數組的元素。 NextDouble ● 傳回一個介于 0.0 和 1.0 之間的随機數。 Sample ● 傳回一個介于 0.0 和 1.0 之間的随機數。 ToString ● 傳回表示目前 Object 的 String。(繼承自 Object。) 用 C# 生成不重複的随機數 我們可以使用兩種方式初始化一個随機數發生器: 第一種方法不指定随機種子,系統自動選取目前時間作為随機種子: Random ro = new Random(); 第二種方法可以指定一個int型參數作為随機種子: int iSeed=10; Random ro = new Random(10); long tick = DateTime.Now.Ticks; Random ran = new Random((int)(tick & 0xffffffffL) | (int) (tick >> 32)); 這樣可以保證99%不是一樣。 之後,我們就可以使用這個Random類的對象來産生随機數,這時候要用到Random.Next()方法。這個方法使用相當靈活,你甚至可以指定産生的随機數的上下限。 不指定上下限的使用如下: int iResult; iResult=ro.Next(); 下面的代碼指定傳回小于100的随機數: int iResult; int iUp=100; iResult=ro.Next(iUp); 而下面這段代碼則指定傳回值必須在50-100的範圍之内: int iResult; int iUp=100; int iDown=50; iResult=ro.Next(iDown,iUp); 除了Random.Next()方法之外,Random類還提供了Random.NextDouble()方法産生一個範圍在0.0-1.0之間的随機的雙精度浮點數: double dResult; dResult=ro.NextDouble(); 但是用Random類生成題号,會出現重複,特别是在數量較小的題目中要生成不重複的的題目是很難的。 參考了網上的一些方法,找到兩類解決方法,一類是通過随機種子入手,使每一次的随機種子不同,來保證不重複;第二類是使用一些資料結構和算法。 下面主要就第二類介紹幾個方法: 方法1:思想是用一個數組來儲存索引号,先随機生成一個數組位置,然後把随機抽取到的位置的索引号取出來,并把最後一個索引号複制到目前的數組位置,然後使随機數的上限減一,具體如:先把這100個數放在一個數組内,每次随機取一個位置(第一次是1-100,第二次是1-99,...),将該位置的數用最後的數代替。
|