【问题标题】:c# - Generating a list of fixtures with the use of randomc# - 使用随机生成固定装置列表
【发布时间】:2014-12-02 22:17:37
【问题描述】:

我正在尝试创建一个用于存储灯具列表的列表方法。目前我的代码的if (fixtures[i] != lineup) 部分不断出现错误,我无法弄清楚为什么。我不断收到以下错误。

在 mscorlib.dll 中发生了“System.ArgumentOutOfRangeException”类型的未处理异常

附加信息:索引超出范围。必须是非负数且小于集合的大小。

我不明白为什么这是个问题,因为如果 fixtures[i] 肯定是 null 那么它应该添加阵容吗?

        private List<string> GenerateFixtures()
    {
        List<string> fixtures = new List<string>(); // Create a new list to store the games
        while (fixtures.Count < 7) // There can only be 6 possible games
        {
            Random random = new Random(DateTime.UtcNow.Millisecond); // Generate a new random
            int home = random.Next(0, 3); // Home team number
            int away = random.Next(0, 3); // Away team number
            if (home == away) // If they are the same teams
            {
                while (home == away) // whilst they are equal to eachother
                {
                    away = random.Next(0, 3); // generate new away team
                }
            }

            string lineup = string.Format("{0} v {1}", home, away); // convert it to a string

            for (int i = 0; i <= fixtures.Count; i++) // whilst i is 0
            {
                if (fixtures[i] != lineup) // if fixtures is not equal to lineup
                    fixtures.Add(lineup); // add it
            }

        } // loop through till it is done
        return fixtures; // then return it
    }

我也有点担心,我会以错误的方式创建它。我有 4 个团队 - 团队 0、1、2、3,他们应该随机互相比赛(我使用随机,所以它总是一个不同的阵容,因为我计划将它用于其他组)。

0 对 1 || 2 对 3 || 2 对 1 || 3 对 0 || 1 对 3 || 0 v 2

有没有更好的方法来做到这一点?

我还刚刚注意到,我这样做的方式将允许将 0 v 1 和 1 v 0 添加到列表中,因为它们是不同的。

【问题讨论】:

  • 你想做什么?创建一个没有重叠的对列表?使用像鸽笼这样的简单算法而不是随机数会好得多。
  • 将 Random 的创建移到循环之外。您可能会得到重复项,并且只需要创建一次。

标签: c# list random


【解决方案1】:

ArgumentOutOfRangeException 表示您正在尝试访问具有数组外部索引的数组成员。

在这一行:

for (int i = 0; i <= fixtures.Count; i++)

您应该将&lt;= 更改为&lt;

【讨论】:

    【解决方案2】:

    您的第一次迭代将导致错误,因为没有Fixtures[0]

    您需要一些确保Fixtures.Count != 0 的原始代码。如果是这样(第一次迭代),请添加第一个阵容:

    if (Fixtures.Count == 0) {
        Fixtures.Add(lineup);
    } else {
        ...
    }
    

    希望这是有道理的

    【讨论】:

      【解决方案3】:

      解决越界错误的简单方法是从测试中删除 for 循环中的 = 符号。您正在测试 count inclusive,它总是比索引高 1。

      改成

      for (int i = 0; i < fixtures.Count; i++) 
      

      至于您的其他问题,好像有更好的方法来解决,这就是我将如何解决问题并解决您对重复问题的担忧,同时解决您遇到的其他问题。

      private List<string> GenerateFixtures(int teamCount, int matchCount)
      {
          var teams = new List<int>(Enumerable.Range(0, teamCount));
          var r = new Random();
      
          var matchups = from t1 in teams
                         from t2 in teams.Where(t => t > t1)
                         select new Tuple<int, int, int>(t1, t2, r.Next());
      
          var matches = matchups.OrderBy(m => m.Item3)
                                .Take(matchCount)
                                .Select(m => string.Format("{0} v {1}", m.Item1, m.Item2))
                                .ToList();
      
          return matches;
      }
      

      它做的第一件事是生成一个团队列表,用于生成所有可能的匹配排列。第一个 LINQ 查询生成所有可能的匹配排列,并将它们与随机数一起分配给一个元组。下一个 LINQ 查询按随机数对匹配进行排序,以保持匹配是随机的要求,然后获取所需的匹配数量。然后它将这些投影到您正在使用的字符串格式中,并将它们放在一个列表中。

      不是唯一的方法,如果你愿意,整个事情可以在一个巨大的 LINQ 查询中完成,但我把它分解了只是为了让它更容易解释。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-15
        • 2021-12-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-03
        • 2020-03-11
        相关资源
        最近更新 更多