要生成1-20的随机数,我需要选择性选择,它不应该是重复的.
如何在C#中执行此操作
注意我需要像这样循环
Random rnd = new Random()
rnd.Next(1,20)
for(int i =0; i<=20;i++)
{
}
Run Code Online (Sandbox Code Playgroud)
对于所有循环,数字应为1到20
Jon*_*eet 22
究竟是什么意思"不应该重复"?如果你的意思是你不想得到任何重复,那么你应该基本上取一个数字1-20的列表,将它们混洗,然后从列表的头部一次抓一个.有关重新排列列表的有效方法,请参阅此Stack Overflow答案.
如果你只是意味着你当前的尝试给出5,5,5,5,5,5,1,1,1,1,1,1,1,1,2,2,2,2,2等等,那么机会是你Random每次选择一个数字时都要创建一个新实例:不要这样做.每次创建实例时,它都会使用当前时间作为随机数生成器的"种子"(除非您明确指定一个).这意味着如果您快速连续创建多个实例,每个实例将获得相同的种子,因此给出相同的数字序列.
相反,使用单个实例Random并重用它.(请注意,它不是线程安全的,这很痛苦.)例如:
private static readonly Random Rng = new Random();
public int NextNumber()
{
return Rng.Next(20) + 1;
}
Run Code Online (Sandbox Code Playgroud)
这不是线程安全的,但如果这是一个问题,请告诉我们.一种替代方案有时会传递给Random方法(当然,这通常会更复杂):
public int NextNumber(Random rng)
{
return rng.Next(20) + 1;
}
Run Code Online (Sandbox Code Playgroud)
然后调用者可以适当地重用该实例.
如果您想要一种生成随机数的线程安全方法,您可能希望StaticRandom在MiscUtil中查看我的类.
(请注意,使用rng.Next(1, 21)也可以正常工作 - 我碰巧更喜欢上面的版本,因为我认为它减少了对包容性/独占边界的猜测,但这是个人品味的问题.)
Hal*_*rim 18
此方法将生成所有数字,并且不会重复任何数字:
/// <summary>
/// Returns all numbers, between min and max inclusive, once in a random sequence.
/// </summary>
IEnumerable<int> UniqueRandom(int minInclusive, int maxInclusive)
{
List<int> candidates = new List<int>();
for (int i = minInclusive; i <= maxInclusive; i++)
{
candidates.Add(i);
}
Random rnd = new Random();
while (candidates.Count > 0)
{
int index = rnd.Next(candidates.Count);
yield return candidates[index];
candidates.RemoveAt(index);
}
}
Run Code Online (Sandbox Code Playgroud)
你可以像这样使用它:
Console.WriteLine("All numbers between 0 and 20 in random order:");
foreach (int i in UniqueRandom(0, 20)) {
Console.WriteLine(i);
}
Run Code Online (Sandbox Code Playgroud)