zoukankan      html  css  js  c++  java
  • 如何生成一组不重复的随机数

    问题:生成随机数的方法有很多,如利用 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

    ...

  • 相关阅读:
    空心杯 电机
    scikit learn 安装
    python fromkeys() 创建字典
    python 清空列表
    mac最常用快捷键
    php while循环
    php 获取某个日期n天之后的日期
    php 添加时间戳
    php 格式化时间
    php 数值数组遍历
  • 原文地址:https://www.cnblogs.com/hellowzl/p/5669674.html
Copyright © 2011-2022 走看看