c# - 使用 LINQ(夹具列表)形成锦标赛表

标签 c# .net linq algorithm

我有一组玩家 (string[]),现在我需要得到一组代表游戏的对 (playerN-playerM) 来组织锦标赛表,如下图所示: enter image description here

期望的最终结果是生成一个包含所有需要进行的比赛的赛程表。

如何使用 LINQ 以高效的方式执行此操作?

更新: A-B、A-C、A-D 不正确 - 游戏应该能够并行运行。 我需要按照与图片相同的顺序得到结果

最佳答案

以下代码可用于为一组球队生成赛程表,以确保每次都与所有其他球队进行 1 场主场比赛和 1 场客场比赛。

代码有点冗长,但它确实可以按照您指定的顺序为您提供一个列表。

代码可能可以优化,但目前这就是我的想法。

注意:生成的列表将包含主场和客场灯具,根据您的网格,这将是您无论如何都需要做的。

    class Fixture
    {
        public string Home { get; set; }
        public string Away { get; set; }
    }

    void CallCode()
    {
        string players = new string[] { "A", "B", "C", "D" };
        List<Fixture> fixtures = CalculateFixtures(players);
    }

    List<Fixture> CalculateFixtures(string[] players)
    {
        //create a list of all possible fixtures (order not important)
        List<Fixture> fixtures = new List<Fixture>();
        for (int i = 0; i < players.Length; i++)
        {
            for (int j = 0; j < players.Length; j++)
            {
                if (players[i] != players[j])
                {
                    fixtures.Add(new Fixture() { Home = players[i], Away = players[j] });
                }
            }
        }

        fixtures.Reverse();//reverse the fixture list as we are going to remove element from this and will therefore have to start at the end

        //calculate the number of game weeks and the number of games per week
        int gameweeks = (players.Length - 1) * 2;
        int gamesPerWeek = gameweeks / 2;

        List<Fixture> sortedFixtures = new List<Fixture>();

        //foreach game week get all available fixture for that week and add to sorted list
        for (int i = 0; i < gameweeks; i++)
        {
            sortedFixtures.AddRange(TakeUnique(fixtures, gamesPerWeek));
        }

        return sortedFixtures;
    }

    List<Fixture> TakeUnique(List<Fixture> fixtures, int gamesPerWeek)
    {
        List<Fixture> result = new List<Fixture>();

        //pull enough fixture to cater for the number of game to play
        for (int i = 0; i < gamesPerWeek; i++)
        {
            //loop all fixture to find an unused set of teams
            for (int j = fixtures.Count - 1; j >= 0; j--)
            {
                //check to see if any teams in current fixtue have already been used this game week and ignore if they have
                if (!result.Any(r => r.Home == fixtures[j].Home || r.Away == fixtures[j].Home || r.Home == fixtures[j].Away || r.Away == fixtures[j].Away))
                {
                    //teams not yet used
                    result.Add(fixtures[j]);
                    fixtures.RemoveAt(j);
                }
            }
        }

        return result;
    }

关于c# - 使用 LINQ(夹具列表)形成锦标赛表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7838168/

相关文章:

c# - 如何重写此 Linq to XML 查询?

.net - 空值不能分配给 Int32 类型的成员,但字符串可以

c# - 来自 aspx 页面中 javascript 函数的变量可在同一 javascript 函数中的 c# 代码中访问

c# - 验证元素的未转义长度

.net - 具有 MVVM 模式的 Wpf Prism 应用程序架构

.net - 如何在运行时在代码中获取NHibernate生成的SQL?

c# - 启动时 .NET 中的控制台应用程序和 Windows 应用程序有什么区别

c# - linq concat 是如何工作的?

c# - 如何在 MVC 中自定义脚手架模板和更改 .cs.t4 文件

c# - 使用 C# 将两个循环转换为单个 LINQ 查询