C#生成指定范围随机数的几种方法

 

在 C# 中,一般都用 Random 产生随机数,它可任意指定产生随机数范围。Random 结合数组,可以产生一些特殊范围的随机数,以满足特殊的需要。如果在循环中产生随机数,由于间隔时间短,每次产生的随机数都一样,需要在循环之前先生成Random对象,这样才能减少产生随机数的重复率。

1、用 Random 生成指定范围内的随机数

(1)生成指定上限的随机数。

例如,生成100以内的随机数:

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

需要注意的是,此种情况下生成的随机数范围是包含上限100的

(2)生成指定上下限的随机数。

例如,生成0到100的随机数:

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

需要注意的是,此种情况下生成的随机数范围包含下限0,但不包含上限100。

 

2、用 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)生成布尔随机数

代码如下:

public bool GenerateBoolRandom()
  {
    bool[] arr = { true, false };
    Random ran = new Random();
    return arr[ran.Next(2)];
  }

调用方法:

Response.Write(GenerateBoolRandom());// 结果 true或false

 

3、用 Random 产生小数随机数

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

(1)把代码封装到一个方法生成小数随机数

代码如下:

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

(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

(3)把代码封装到一个类

代码如下:

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

 

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

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

(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
}

 

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

(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

 

参考资料http://www.liangshunet.com/ca/201307/337451622.htm

—— 完 ——
相关推荐
评论

立 为 非 似

中 谁 昨 此

宵 风 夜 星

。 露 , 辰

文章点击榜

细 无 轻 自

如 边 似 在

愁 丝 梦 飞

。 雨 , 花