首页 > 解决方案 > 根据优先级 C# 将两个列表合并为一个并拆分重叠

问题描述

我将这两个列表安排为优先级 1 并注册为优先级 0:

在此处输入图像描述

结果应该是:

在此处输入图像描述

我想将两个列表合并为一个并检查优先级。将输入优先行而不进行拆分。但是可以拆分未优先级的行。

标签: c#algorithmsortingmergesplit

解决方案


假设Scheduled包含所有优先级为 1 的周期,并且Registered包含所有优先级为 0 的周期(这些被认为是unprioritized),并假设您的周期在一个名为的类中ClassPeriod,并假设Priority是 aNullable代表结果图中的空白列(您的问题应该已经回答所有这些都清楚),那么您可以在以下位置定义一个辅助方法ClassPeriod

public class ClassPeriod {
    public double From;
    public double To;
    public int? Priority;

    public bool ContainsFrom(ClassPeriod aCP) => From <= aCP.From && aCP.From < To;
    public bool ContainsTo(ClassPeriod aCP) => From < aCP.To && aCP.To <= To;
}

现在您可以将答案计算为:

var ans = Scheduled
            .Select(s => new ClassPeriod { From = s.From, To = s.To })
            .Concat(
                Registered.SelectMany(r => {
                    var ans = new List<ClassPeriod>();
                    while (r.From < r.To) {
                        var pcp = new ClassPeriod {
                            From = Scheduled.Where(s => s.ContainsFrom(r)).Select(s => s.To).DefaultIfEmpty(r.From).Max(),
                            To = Scheduled.Where(s => s.ContainsTo(r)).Select(s => s.From).DefaultIfEmpty(r.To).Min()
                        };

                        var nexts = Scheduled.Where(s => pcp.ContainsFrom(s));
                        if (nexts.Any()) {
                            var nextTo = nexts.Min(s => s.From);
                            ans.Add(new ClassPeriod { From = pcp.From, To = nextTo });
                            r.From = nextTo;
                        }
                        else {
                            if (pcp.From < pcp.To)
                                ans.Add(pcp);
                            break;
                        }
                    }
                    return ans;
                })
            )
            .OrderBy(cp => cp.From).ThenBy(cp => cp.To);

推荐阅读