zoukankan      html  css  js  c++  java
  • C#产生指定范围随机数(整数、小数、字符、布尔,相对不重复的和唯一的)的几种方法

    在 C# 中,一般都用 Random 产生随机数,它可任意指定产生随机数范围。

    Random 结合数组,可以产生一些特殊范围的随机数,以满足特殊的需要。如果在循环中产生随机数,由于间隔时间短,每次产生的随机数都一样,需要先生成种子(有 3 种方法),再用该种子产生随机数,或者锁住 Random 对象,这样才能减少产生随机数的重复率。如果要产生唯一的随机数(有 4 种方法),需要用数组或检查已产生随机数是否重复的办法。

    一、用 Random 产生指定范围随机数(整数随机数)

    1、产生指定上限的随机数(如产生100以内的随机数)

    Random ran = new Random();
    int n = ran.Next(100);
    

    2、产生指定上下限的随机数(如产生100到1000的随机数)

    Random ran = new Random();
    int n = ran.Next(100, 1000);
    

    二、用 Random 结合数组产生指定范围随机数(字符和布尔随机数)

    在某些情况下,随机数只能取一些特殊指定的值,如不连续的数字或指定的一些单词等,此时仅用 Random 无法达到要求,必须借住数组才能实现。
    实现思路大概是这样:先把这些特殊的值存到数组中,然后把数组的长度作为 Random 的上限产生随机数,此随机数正是数组的下标,根据该下标取得数组的值。

    (一)产生字符随机数

    1、产生不连续或指定值的随机数

    public string GetRandom(string[] arr)
      {
        Random ran = new Random();
        int n = ran.Next(arr.Length - 1); 
        return arr[n];
      }
    
    //调用方法:
    string[] arr = { "25", "28", "30", "50", "60" };
      GetRandom(arr);
    

    2、生成保留指定小数位数(例如 2 位)的随机数

    假如要用指定单词作为随机数的取值,代码实现跟上例相同,所不同的仅是随机数的取值,所以只要定义一个单词数组直接调用上面代码即可。
    调用方法:

    string[] arr = { "red", "green", "blue", "orange", "white" };
      GetRandom(arr);
    

    (二)产生布尔随机数

    public bool GenerateBoolRandom()
      {
        bool[] arr = { true, false };
        Random ran = new Random();
        return arr[ran.Next(2)];
      }
    
    //调用方法:
    Response.Write(GenerateBoolRandom());// 结果 true
    

    三、用 Random 产生小数随机数

    在默认情况下,C# 只能产生任意小数随机数,如果要产生指定范围小数随机数,需要自己写代码。写代码时,既可以把它们封装到一个方法中又可以封装到一个类中,后者可重载 C# 的 NextDouble() 方法。

    1、把代码封装到一个方法

    A、生成小数随机数

    public double NextDouble(Random ran, double minValue, double maxValue)
      {
         return ran.NextDouble() * (maxValue - minValue) + minValue;
      }
    
    //调用:
    
      Random ran = new Random();
      double randNum = NextDouble(ran, 1.52, 2.65);
      Response.Write(randNum);// 结果 2.30927768119112
    

    B、生成保留指定小数位数(例如 2 位)的随机数

    public double NextDouble(Random ran, double minValue, double maxValue, int decimalPlace)
      {
         double randNum = ran.NextDouble() * (maxValue - minValue) + minValue;
         return Convert.ToDouble(randNum.ToString("f" + decimalPlace));
      }
    
    //调用:
      Random ran = new Random();
      double randNum = NextDouble(ran, 5.16, 8.68, 2);// 保留两位小数
      Response.Write(randNum);// 结果 8.46
    

    2、把代码封装到一个类

    using System;
      using System.Text;
    
    public static class RandomDoubleRange
      {
        public static double NextDouble(this Random ran, double minValue, double maxValue)
        {
          return ran.NextDouble() * (maxValue - minValue) + minValue;
        }
    
      public static double NextDouble(this Random ran, double minValue, double maxValue, int decimalPlace)
        {
          double randNum = ran.NextDouble() * (maxValue - minValue) + minValue;
           return Convert.ToDouble(randNum.ToString("f" + decimalPlace));
        }
      }
    
    //调用:
      Random ran = new Random();
      double randNum1 = ran.NextDouble(5.16, 8.68);
      double randNum2 = ran.NextDouble(5.16, 8.68, 2);//保留两位小数
      Response.Write(randNum1 + "; " + randNum2);//结果 7.41055195257559; 6.69
    

    四、产生相对不重复的随机数

    当在一个循环中生成随机数,由于生成随机数的时间间隔比较短,容易产生重复的随机数,如果要产生不重复的随机数,需要用种子或把随机数对象锁住,以下是它们的实现方法。

    1、用种子产生相对不重复的随机数

    生成种子方法一:

    public static int GenerateRandomSeed()
      {
        return (int)DateTime.Now.Ticks;
      }
    
    //产生 1 到 10 的随机数为:2, 5, 2, 5, 7, 3, 4, 4, 6, 3
    

    生成种子方法二:

    using System.Text.RegularExpressions;
    
    public static int GenerateRandomSeed()
      {
        return Convert.ToInt32(Regex.Match(Guid.NewGuid().ToString(), @"\d+").Value);
      }
    
    //产生 1 到 10 的随机数为:1, 7, 4, 9, 8, 1, 8, 7, 9, 8
    

    生成种子方法三:

    using System.Security.Cryptography;
    
    public static int GenerateRandomSeed()
      {
        byte[] bytes = new byte[4];
        RNGCryptoServiceProvider rngCSP = new RNGCryptoServiceProvider();
        rngCSP.GetBytes(bytes);
        return BitConverter.ToInt32(bytes, 0);
      }
    
    //产生 1 到 10 的随机数为:4, 8, 7, 2, 6, 7, 6, 5, 5, 7
    

    产生指定数目的随机数并存到数组:

    // randNum 为产生随机数的数目
        public int[] GenerateRandom(int minValue, int maxValue, int randNum)
        {
            Random ran = new Random(GenerateRandomSeed());
            int[] arr = new int[randNum];
    
        for (int i = 0; i < randNum; i++)
            {
                arr[i] = ran.Next(minValue, maxValue);
            }
            return arr;
        }
    
    //调用方法:
      int[] arr = GenerateRandom(1, 10, 10);
      string temp = string.Empty;
      for (int i = 0; i < arr.Length; i++)
      {
        temp += arr[i].ToString() + ", ";
      }
      Response.Write(temp);
    

    2、通过锁住 Random 对象产生相对不重复的随机数

    产生随机数:

    public int GenerateRandom(Random ran, int minValue, int maxValue)
      {
        lock (ran) // 锁住 Random 对象
        {
          return ran.Next(minValue, maxValue);
        }
      }
    
    //调用:
      int[] arr = new int[5];
      Random ran = new Random();
      for (int i = 0; i < 5; i++)
      {
        arr[i] = GenerateRandom(ran, 1, 10);// 结果 5, 7, 2, 5, 2
       }
    

    五、生成绝对不重复的指定范围的随机数

    1、方法一:先生成一个索引数组,再把产生的随机数作为索引从该数组中取一个数作为随机数。

    生成随机数:

    // n 为生成随机数个数
      public int[] GenerateUniqueRandom(int minValue, int maxValue, int n)
      {
        //如果生成随机数个数大于指定范围的数字总数,则最多只生成该范围内数字总数个随机数
        if (n > maxValue - minValue + 1)
          n = maxValue - minValue + 1;
    
      int maxIndex = maxValue - minValue + 2;// 索引数组上限
        int[] indexArr = new int[maxIndex];
        for (int i = 0; i < maxIndex; i++)
        {
          indexArr[i] = minValue - 1;
          minValue++;
        }
    
      Random ran = new Random();
        int[] randNum = new int[n];
        int index;
        for (int j = 0; j < n; j++)
        {
          index = ran.Next(1, maxIndex - 1);// 生成一个随机数作为索引
    
          //根据索引从索引数组中取一个数保存到随机数数组
          randNum[j] = indexArr[index];
    
          // 用索引数组中最后一个数取代已被选作随机数的数
          indexArr[index] = indexArr[maxIndex - 1];
          maxIndex--; //索引上限减 1
        }
        return randNum;
      }
    
    //调用方法:
    
    GenerateUniqueRandom(1, 10, 10);// 结果 9, 5, 10, 1, 7, 3, 2, 4, 6, 8
    
    GenerateUniqueRandom(1, 10, 5);// 结果 3, 7, 6, 1, 9
    

    2、方法二:用 do...while 循环来生成不重复的随机数,用 for 循环来检查产生的随机数是否重复,只有不重复的随机数才保存到数组。

    生成随机数:

    // n 生成随机数个数
      public int[] GenerateUniqueRandom(int minValue, int maxValue, int n)
      {
        // Random.Nex(1, 10) 只能产生到 9 的随机数,若要产生到 10 的随机数, maxValue 要加 1
        maxValue++;
    
      // Random.Nex(1, 10) 只能产生 9 个随机数,因此 n 不能大于 10 - 1
        if (n > maxValue - minValue)
          n = maxValue - minValue;
    
      int[] arr = new int[n];
        Random ran = new Random((int)DateTime.Now.Ticks);
    
      bool flag = true;
        for (int i = 0; i < n; i++)
        {
          do
          {
            int val = ran.Next(minValue, maxValue);
            if (!IsDuplicates(ref arr, val))
            {
              arr[i] = val;
              flag = false;
            }
          } while (flag);
          if (!flag)
            flag = true;
        }
        return arr;
      }
    
    // 查检当前生成的随机数是否重复
      public bool IsDuplicates(ref int[] arr, int currRandNum)
      {
        bool flag = false;
        for (int i = 0; i < arr.Length; i++)
        {
          if (arr[i] == currRandNum)
          {
            flag = true;
            break;
          }
        }
        return flag;
      }
    
    //调用方法:
    
     int[] arr = GenerateUniqueRandom(1, 10, 10);// 生成 10 个 1 到 10 的随机数
      for (int i = 0; i < arr.Length; i++)
      Response.Write(arr[i] + ", ");// 结果 10, 7, 9, 4, 3, 5, 1, 2, 6, 8
    
      GenerateUniqueRandom(1, 10, 5);// 生成 5 个 1 到 10 的随机数,结果 9, 1, 7, 2, 10
    

    3、方法三:用 do...while 循环来检查产生的随机数是否重复,只有不重复的随机数才保存到哈希表。

    生成随机数:

    using System.Collections;
    
    // n 为生成随机数个数
      public Hashtable GenerateUniqueRandom(int minValue, int maxValue, int n)
      {
        // Random.Next(1, 10) 只能产生到 9 的随机数,若要产生到 10 的随机数,maxValue 要加 1
        maxValue++;
    
      // Random.Next(1, 10) 只能产生 9 个随机数,因此 n 不能大于 10 - 1
        if (n > maxValue - minValue)
          n = maxValue - minValue;
    
      Hashtable ht = new Hashtable();
        Random ran = new Random((int)DateTime.Now.Ticks);
    
      bool flag = true;
        for (int i = 0; i < n; i++)
        {
          do
          {
            int val = ran.Next(minValue, maxValue);
            if (!ht.ContainsValue(val))
            {
              ht.Add(i, val);
              flag = false;
            }
          } while (flag);
          if (!flag)
            flag = true;
        }
        return ht;
      }
    
    //调用方法:
    
      Hashtable ht = GenerateUniqueRandom(1, 10, 10);// 生成 10 个 1 到 10 的随机数
      foreach (DictionaryEntry de in ht)
      Response.Write(de.Value.ToString() + ", ");// 结果 10, 7, 9, 4, 3, 5, 1, 2, 6, 8
    
      GenerateUniqueRandom(1, 10, 5);// 生成 5 个 1 到 10 的随机数,结果 4, 10, 9, 7, 6
    

    4、方法四:用 Linq 生成不重复的随机数

    生成随机数:

    using System.Linq;
    
    public IEnumerable<int>
      GenerateNoDuplicateRandom(int minValue, int maxValue)
      {
        return Enumerable.Range(minValue, maxValue).OrderBy(g => Guid.NewGuid());
      }
    
    //调用方法:
    
    IEnumerable<int> list = GenerateNoDuplicateRandom(1, 10);
      string str = string.Empty;
      foreach (int item in list)
      {
        str += item.ToString() + ", ";
      }
      Response.Write(str);// 结果 5, 2, 10, 1, 7, 6, 8, 3, 9, 4
    

    以上几种产生指定随机数的方法,都通过测试,可根据实际开发需要灵活选择,一般情况都是直接用 Random 就可以了。

  • 相关阅读:
    C#与C++与互操作
    WPF GridView动态添加项并读取数据
    C#使用消息队列(MSMQ)
    使用代码浏览WPF控件模版
    PowerShell将运行结果保存为文件
    opencv + ffmpeg
    vmware
    HttpComponents Downloads
    pytorch 安装
    opencv 3.4.0 的编译
  • 原文地址:https://www.cnblogs.com/qingheshiguang/p/15806915.html
Copyright © 2011-2022 走看看