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 就可以了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM