没有重复的数字列表

时间:2018-05-25 00:08:40

标签: c#

我需要打印1到99之间的随机数而不重复它们。 以下代码给出了堆栈溢出。

int newNumb= Random.Range(1, 99);
if(acum.Count > 0)
{
    while (acum.Contains(newNumb))
    {
         newNumb= Random.Range(1, 99);
    }
}

5 个答案:

答案 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