问题:生成随机数的方法有很多,如利用 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} 个随机数: ", count); System.Console.Write(string.Join(" ", data1) + " "); //产生随机数的方法二 data2 = pro.GetRandomData2(count); //输出随机数 System.Console.Write("方法二产生了 {0} 个随机数: ", count); System.Console.Write(string.Join(" ", data2) + " "); //产生随机字符串 System.Console.Write("产生了 10 个随机字符串: "); for (int i = 0; i < 10; i++) { System.Console.Write("{0} ", 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
...