我需要打印1到99之间的随机数而不重复它们。 以下代码给出了堆栈溢出。
int newNumb= Random.Range(1, 99);
if(acum.Count > 0)
{
while (acum.Contains(newNumb))
{
newNumb= Random.Range(1, 99);
}
}
答案 0 :(得分:4)
这个问题的典型解决方案是生成顺序排序范围从1到99然后 shuffle :
static Random _random = new Random();
public static void Shuffle<T>(IList<T> items)
{
for (int i = thisList.Count - 1; i > 0; i--)
{
int j = _random.Next(0, i);
T tmp = items[i];
items[i] = items[j];
items[j] = tmp;
}
}
var numbers = Enumerable.Range(1,99).ToList();
Shuffle(numbers);
foreach (var number in numbers)
{
Console.WriteLine(number);
}
答案 1 :(得分:0)
这将生成随机整数列表,每次都是不同的整数,并将其添加到列表中。
shuffle方法更好,但由于范围非常有限,同时丢弃重复的数字也可以。
超过100次运行,使用StopWatch()
测量经过的时间,列表生成从未超过200个刻度。
洗牌清单在我的机器上5次(1029~1395 Ticks)。
如果列表计数设置为值&gt;然后是上限范围(在这种情况下为100+),生成过程当然永远不会结束。没有足够的不同随机值来填充列表。
Random random = new Random();
List<int> acum = new List<int>();
while (acum.Count < 99)
{
int Number = random.Next(1, 100);
if (!acum.Contains(Number))
{
acum.Add(Number);
}
}
要验证结果,请订购列表并查看其从1到99的排序:
List<int> acum2 = acum.OrderBy(n => n).ToList();
答案 2 :(得分:-1)
执行此操作的最佳方法是生成所有必需的数字,然后从该列表中拉出直至其为空,创建新订单;这通常被称为改组。
您当前的代码占用时间太长,您需要跟踪已选择的数字,并且只选择剩余的数字。在psudocode
generate list
while list not empty
choose number from list
remove it from list
add to new list
答案 3 :(得分:-1)
这样做只是:
var list = new List<int>();
for (int i = 0; i < 99; i++)
{
list.Add(i);
}
var resultList = list.OrderBy(i => Guid.NewGuid());
或者@Camilo建议:
var resultList = Enumerable
.Range(0, 99)
.OrderBy(i => Guid.NewGuid());
此解决方案似乎效率低下。请使用 fischer-yates 随机播放(显示在@ Joel的回答中)。
答案 4 :(得分:-2)
非效率方式(见评论):
Random rand = new Random();
HashSet<int> randomHashSet = new HashSet<int>();
while (randomHashSet.Count < 99)
randomHashSet.Add(rand.Next(1, 100));
List<int> randomList = randomHashSet.ToList();
<强>更新强>
高效的方式:
Random r = new Random();
var result = Enumerable.Range(1, 99).ToList();
for (int i = 0, j = r.Next(0, 99); i < 99; i++, j = r.Next(0, 99))
result[i] = result[i] + result[j] - (result[j] = result[i]); // Swap