我想随机取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);
}
}
}
答案 0 :(得分:6)
我建议只创建一个包含50个可能数字的列表(或数组),然后对其进行混洗,而不是循环直到找到尚未使用的数字。然后你可以选择你想要的很多。
Stack Overflow上有很多改组问题,例如this one。
这样做的好处是性能完全可预测且线性 - 而如果你从50个中取出所有50个数字,最后你将不得不继续生成随机数,直到你发生得到最后一个。对于50来说并不是那么糟糕,但想象一下,如果你有成千上万的数字......
(另请注意,您现有的代码不会在任何地方使用数字20,如果您只想生成20个数字,这应该会响起警报......)
答案 1 :(得分:1)
只有代码出现问题的情况是,如果找到重复项,您仍然会增加循环并且不会获取队列中的所有值(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);
答案 2 :(得分:1)
我认为你强迫它找到50个不同的数字,而只允许它从49个可能的数字中产生它们。请改为rm.Next(50) + 1
。
答案 3 :(得分: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);
这将提供更可预测的表现。
答案 4 :(得分:0)
按照你的逻辑,写这个可能更简单:
var results = new HashSet<int>();
var random = new Random();
while (results.Count < 20)
{
results.Add(random.Next(1, 50));
};
无需检查该号码是否已添加到Hashset 因为每个号码只会被添加一次......
然而......这只是一个快速解决方案,可帮助您了解您尝试解决的问题,(基本上是课堂示例) 但你真的应该接受Jon Skeet提供的建议,因为你不知道执行上面代码需要多长时间。
另一件需要注意的事情是你正在使用Queue类,它类似于FIFO缓冲区......它并不真正适用于你的问题。