問題:生成隨機數的方法有很多,如利用 C# 中的 Random 類中 Next() 方法就可以生成。但是這樣生成的隨機數有可能會重復,如果需要生成不同的隨機數,有沒有相應的高效的方法呢?
分析:1.獲取生成隨機數的方法,這里用 Next 方法
2.在生成隨機數之后立刻判斷它是否與之前生成的重復,如果重復則重新生成,否則繼續生成下一個
3.優化循環語句
C#代碼:
using System; using System.Threading; namespace MyTest { public class Program { static void Main(string[] args) { //隨機數的個數 int count = 100; int[] data1 = new int[count]; int[] data2 = new int[count]; //調用不同的方法,產生隨機數 Program pro = new Program(); //產生隨機數的方法一 data1 = pro.GetRandomData1(count); //輸出隨機數 System.Console.Write("方法一產生了 {0} 個隨機數:\r\n", count); System.Console.Write(string.Join(" ", data1) + "\r\n"); //產生隨機數的方法二 data2 = pro.GetRandomData2(count); //輸出隨機數 System.Console.Write("方法二產生了 {0} 個隨機數:\r\n", count); System.Console.Write(string.Join(" ", data2) + "\r\n"); //產生隨機字符串 System.Console.Write("產生了 10 個隨機字符串:\r\n"); for (int i = 0; i < 10; i++) { System.Console.Write("{0}\r\n", pro.GetRandomStr(4)); //產生一個隨機字符串后,線程停頓1毫秒,防止重復 Thread.Sleep(1); } System.Console.ReadKey(); } /// <summary> /// 功能:產生不同的隨機數,方法一 /// 特點:和 GetRandomDatas2 方法相比,空間上節省了一個數組,但時間效率很低 /// </summary> /// <param name="count">隨機數的個數</param> /// <returns>產生的所有隨機數</returns> public int[] GetRandomData1(int count) { int data = 0; int[] arr = new int[count]; Random rand = new Random(); //產生N個不同的隨機數 for (int i = 0; i < count; i++) { data = rand.Next(0, count); //檢測當前隨機數是否在之前出現過 for (int j = 0; j < i; j++) { //如果之前出現過,則重新產生隨機數,並重新檢測 if (arr[j] == data) { data = rand.Next(0, count); j = -1; } } //如果之前未出現,則保存當前隨機數 arr[i] = data; } return arr; } /// <summary> /// 功能:產生不同的隨機數,方法二 /// 特點:和 GetRandomDatas1 方法相比,時間效率高很多,但多用了一個數組boo[],空間開銷較大 /// 適用范圍:該方法只適用產生 “整數” 的隨機數的問題,不適用產生非整數隨機數:小數、負數等 /// </summary> /// <param name="count">隨機數的個數</param> /// <returns>產生的所有隨機數</returns> public int[] GetRandomData2(int count) { int data = 0; int[] arr = new int[count]; bool[] boo = new bool[count]; Random rand = new Random(); for (int i = 0; i < count; i++) { do { // 如果產生的數相同繼續循環 data = rand.Next(count); } while (boo[data]); boo[data] = true; arr[i] = data; } return arr; } /// <summary> /// 附加功能:產生一個隨機純數字的字符串(如:驗證碼,也可以直接用 rand.Next(int minValue, int maxValue) 產生) /// 問題:如果產生兩個隨機字符串的時間間隔太短,有可能會出現重復的字符串 /// </summary> /// <param name="strLength"></param> /// <returns></returns> private string GetRandomStr(int strLength) { string randomStr = ""; int temp = -1; char[] allChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; Random rand = new Random(); for (int i = 0; i < strLength; i++) { if (temp != -1) { rand = new Random(i * temp * ((int)DateTime.Now.Ticks)); } int t = rand.Next(allChars.Length); if (temp == t) { return GetRandomStr(strLength); } temp = t; randomStr += allChars[t]; } return randomStr; } } }
運行結果:
方法一產生了 100 個隨機數:
80 29 14 60 8 33 66 65 93 55 15 ...
方法而產生了 100 個隨機數:
80 29 14 60 8 33 66 65 93 55 15 ...
產生了 10 個隨機字符串:
8781
1957
1342
1528
1351
...