小编典典

C#中的循环竞赛算法

algorithm

我在实现这个小循环项目方面遇到了一些麻烦。我想做的是生成游戏的预览日历

然后我想输出;

第1天:第1队对第2队;第3队对第4队;第5小组对第6小组;

第2天1队vs 4队;第6队对第3队;第2队对第5队;

直到冠军结束;

这是我到目前为止的代码,但是当数组的其余部分旋转时,我很难让第一支队伍修复…:

static void Main(string[] args)
   {
        string[] ListTeam = new string[] {"Equipe1", "Equipe2", "Equipe3", "Equipe4", "Equipe5", "Equipe6"};
        IList<Match> ListMatch = new List<Match>();
        it NumberOfDays = (ListTeam.Count()-1);
        int y = 2;

        for (int i = 1; i <= NumberOfDays; i++)
        {
            Console.WriteLine("\nDay {0} : \n",i);
            Console.WriteLine(ListTeam[0].ToString() + " VS " + ListTeam[i].ToString());

            for (y =ListTeam.Count(); y>0 ; y--)
            {
                Console.WriteLine(ListTeam[y].ToString() + " VS " + ListTeam[y+1].ToString());
                y++;
            }

        }
    }

编辑:我在Java中找到一个代码示例,但我无法翻译…


阅读 432

收藏
2020-07-28

共1个答案

小编典典

使用模块化算法可以很容易做到这一点:

更新2 :( 如所承诺的正确算法)

public void ListMatches(List<string> ListTeam)
{
    if (ListTeam.Count % 2 != 0)
    {
        ListTeam.Add("Bye");
    }

    int numDays = (numTeams - 1);
    int halfSize = numTeams / 2;

    List<string> teams = new List<string>();

    teams.AddRange(ListTeam.Skip(halfSize).Take(halfSize));
    teams.AddRange(ListTeam.Skip(1).Take(halfSize -1).ToArray().Reverse());

    int teamsSize = teams.Count;

    for (int day = 0; day < numDays; day++)
    {
        Console.WriteLine("Day {0}", (day + 1));

        int teamIdx = day % teamsSize;

        Console.WriteLine("{0} vs {1}", teams[teamIdx], ListTeam[0]);

        for (int idx = 1; idx < halfSize; idx++)
        {               
            int firstTeam = (day + idx) % teamsSize;
            int secondTeam = (day  + teamsSize - idx) % teamsSize;
            Console.WriteLine("{0} vs {1}", teams[firstTeam], teams[secondTeam]);
        }
    }
}

它将打印每天的团队比赛。

让我快速尝试解释该算法如何工作:

我注意到,由于我们正在轮换除第一支球队之外的所有球队,因此,如果将除第一支球队之外的所有球队都放在一个数组中,那么我们应该使用基于日期的索引偏移量从该数组中读取第一支球队,然后正确环绕的模运算。在实践中,我们会将数组视为在两个方向上无限重复,并且将视图逐渐向右(或向左)滑动。

但是有一个障碍,那就是我们必须以一种非常特殊的方式订购团队,以使其正常工作。否则,我们将无法正确旋转。因此,我们还需要以一种非常特殊的方式来阅读匹配的第二支球队。

准备列表的正确方法如下:

  • 切勿将第一队(第1队)列入名单。
  • 将团队列表的后半部分放在列表的前面。
  • 取出列表的前半部分,将其反转并放入列表中(而不是Team#1)。

现在,读取列表的正确方法如下:

  • 对于每一天,请增加您正在查看的第一个索引1
  • 对于您在该位置看到的第一个团队,将该团队与Team#1匹配。
  • 对于列表((day + idx) % numDays)中的下一个球队,我们通常将其与抵消了一半球队数量减去1(因为我们自己处理第一个比赛的团队,减去1)的球队相匹配。但是,由于列表的后半部分是通过还原准备的,因此我们需要在列表的还原后的后半部分中匹配该偏移量。一种更简单的方法是观察到,这等效于匹配相同的索引,但从列表的末尾开始。给定当前day偏移量为(day + (numDays - idx)) % numDays

更新3:
我不高兴我的解决方案涉及到数组元素的这种复杂选择,匹配和反转。在考虑了解决方案涉及的内容之后,我意识到我太想保持团队的秩序了。但是,这不是必需的,并且不必关心初始订购即可获得不同但同样有效的时间表。重要的是我在解释的第二部分中描述的选择算法。

因此,您可以简化以下几行:

teams.AddRange(ListTeam.Skip(halfSize).Take(halfSize));
teams.AddRange(ListTeam.Skip(1).Take(halfSize -1).ToArray().Reverse());

至:

teams.AddRange(ListTeam); // Copy all the elements.
teams.RemoveAt(0); // To exclude the first team.
2020-07-28