【问题标题】:array of integers with 1000 elements (1to1000) in random order具有 1000 个元素 (1to1000) 的整数数组,以随机顺序排列
【发布时间】:2014-09-16 00:47:15
【问题描述】:

编程新手 我想编写一个函数,它返回一个包含 1000 个元素的整数数组,其中包含随机顺序的值 1 到 1000。

private static void RandomNum()
    {
        //Initialize an array
        int[] randomList = new int[1000];
        //Initialize an instance of random class
        Random rnd = new Random();
        // integer variable
        int counter = 0;



            while (counter < 1000)
            {
                //store random num 
                int random = rnd.Next(1, 1001);


                if (Array.IndexOf(randomList, random) <= 0)
                {
                    //store random number into Array
                    randomList[counter] = random;
                    counter++;
                }

            }


        //output elements in Array
        for (int i = 0; i < 1000; i++)
        {
            Console.WriteLine(randomList[i]);
        }
        //output number of elements in Array
        Console.WriteLine(counter);
        Console.Read();
    }

任何帮助将不胜感激。

【问题讨论】:

  • Array.IndexOf(randomList, random) &lt;= 0 似乎是一个错误,因为它包含零,这是一个有效的索引(第一个)。如果代码旨在避免重复,它将在所有等于第一个的随机数上失败。相反,您可以使用 &lt; 0!randomList.Contains(random)
  • @TimSchmelter 不错的收获。使用数组而不是列表是否有原因?如果使用列表,您可以这样做 List.Contains(random) 并避免重复。
  • @PWilliams0530:你仍然可以使用Enumerable.Contains(如评论)。我不知道他为什么需要一个数组,但因为他想要 1000 个随机数,所以大小是已知的,而且数组似乎是合适的。
  • 不确定海报的技能水平在哪里(因为他们说他们是编程新手) - 但请查看:stackoverflow.com/questions/5561742/…

标签: .net arrays function random integer


【解决方案1】:

这会检查rnd.Next(1, 1001) 生成的数字random 是否存在于数组randomList 中。如果它不存在,则将其存储在数组randomList 中由counter 指定的索引中。

如果您想生成一些随机排序,可以使用一些 LINQ:

private static void RandomNum()
{
    Random rnd = new Random();
    var randomList = Enumerable.Range(1,1000)
        .OrderBy(x=>rnd.Next(1,1000))
        .ToArray();

    foreach(var item in randomList)
    {
        Console.WriteLine(item);
    }
    //output number of elements in Array
    Console.WriteLine(randomList.Count());
    Console.Read();
}

【讨论】:

  • 我不这么认为,因为Enumerable.Range(1,1000) 将确保我们获得 1000 个不同的值。然后我使用order = rnd.Next(1,1000) 随机排列它们,但我只按顺序使用它。尽管rnd.Next(1,1000) 可能会为两个值生成完全相同的数字,但这仅意味着它们将是一个相邻的值。那里没有重复。
  • 不需要 .Select(x => x)
  • 是的...这是从之前的编辑中留下的,我实际上正在生成一个order 属性,该属性将用于对其进行排序,然后仅选择范围的结果。我已经将它们删除为不必要的
【解决方案2】:

懒人随机排序的方法是:

Enumerable.Range(1, 1000).OrderBy(x=>System.Guid.NewGuid());

不一定是好的随机化,但它随机的。

另一种更随机但空间/时间要求稍高的方式是:

var rnd = new Random();
var numbers = Enumerable.Range(1, 1000).ToList();
var randomizedNumbers = new List<int>();
while (numbers.Count > 0)
{
    var removeIndex = rnd.Next(0, numbers.Count - 1);
    var number = numbers[removeIndex];
    randomizedNumbers.Add(number);
    numbers.RemoveAt(removeIndex);
}

这只是不断地从第一个列表中取出一个随机数并将其放入一个新集合中,直到第一个列表为空。

或者,正如其他人所说,最好的方法是使用Fisher-Yates shuffle

【讨论】:

  • 我不确定 Guid 究竟是如何生成的,但假设它们像 Random.Next 一样随机,那么它可能比上面的要好,因为它更有效。
  • @Chris GUID 技巧很简洁,在大多数情况下可能就足够了,但它的效率低于 Fisher-Yates。 Fisher-Yates 在正确实施时为 O(n),而 GUID 技巧中的 .OrderBy 将进行比较排序,即 O(n log n)。
  • @Techrocket9:是的。同意。我不再确定“上述”指的是什么,但我认为我的意思是原始帖子。我怀疑我还试图指出它仍然是一个“良好的随机化”,因为只要 GUID 是随机生成的,它就会像其他任何东西一样随机。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-19
  • 2012-08-21
  • 2012-11-19
  • 1970-01-01
  • 2014-09-15
  • 2012-05-28
  • 2018-12-13
相关资源
最近更新 更多