在c#中使用Random生成50个随机数



我想随机取50个数字,这样使用随机方法就不会重复。

以下是我到目前为止的代码:

private void settext()
{      
     int i;
     Queue <int> qe= new Queue<int>(50);
     Random rm= new Random();
     for (int g = 0; g < 50; g++)
     {
         i = rm.Next(1, 50);
         if (!qe.Contains(i))
         {
              qe.Enqueue(i);
         }                
     }
 }

与其循环直到找到一个还没有使用过的数字,我建议您只创建一个包含50个可能数字的列表(或数组(,然后对其进行混洗。然后您可以随心所欲地使用它们。

在Stack Overflow上有很多混乱的问题,比如这个问题。

这样做的优点是性能是完全可预测的和线性的,而如果你把50个数字中的所有50个都取出来,最后你必须不断生成随机数,直到发生才能得到最后一个。50还不错,但想象一下,如果你有几十万个数字。。。

(还要注意,您现有的代码在任何地方都不使用数字20,如果您试图只生成20个数字,这应该会敲响警钟…(

我认为,你强迫它找到50个不同的数字,而只允许它从49个可能的数字中生成它们。请改用rm.Next(50) + 1

使用Linq怎么样?

private static Random rand = new Random();
var twentyUniqueNumbers = RandomNumberStream().Distinct().Take(20);
IEnumerable<int> RandomNumberStream()
{
  yield return rand.Next(1,50);
}

或者更好的是,创建一个50个数字的列表,洗牌,然后取20。。。

var twentyUniqueNumbers = Enumerable.Range(0,50)
                                    .OrderBy(s => rand.Next());
                                    .Take(20);

这将提供更可预测的性能。

您的代码唯一的问题是,如果发现重复,您仍然在递增循环,并且没有获得队列中的所有值(50(。您可以使用while循环,并且只有在找到不重复的值时才递增索引。

int index=0;
int i;
Queue<int> qe = new Queue<int>(50);
Random rm = new Random();
while(index< 50)
{
    i = rm.Next(1, 51); //to get from 1 to 50
    if (!qe.Contains(i)) //to check for duplicate
    {
        qe.Enqueue(i);
        ++index;
    }
}

以上将生成50个唯一的随机数,如果你想从中提取20个数字,那么:

var numbers = qe.Take(20);

根据您的逻辑,编写以下内容可能更简单:

var results = new HashSet<int>();
var random = new Random();
while (results.Count < 20)
{
    results.Add(random.Next(1, 50));
};

无需检查数字是否已添加到哈希集中因为每个数字只能加一次。。。

然而。。。这只是一个快速的解决方案,可以帮助你理解你试图解决的问题(这基本上是教室的例子(但你真的应该接受Jon Skeet提供的建议,因为你不知道执行上面的代码实际需要多长时间。

另一件需要注意的事情是,您正在使用Queue类,该类旨在像FIFO缓冲区一样使用。。。这并不适用于你的问题。

最新更新