【发布时间】:2022-01-10 01:10:24
【问题描述】:
我目前正在寻找一种可以帮助我压缩更改列表的算法。
更改类如下所示
public class change
{
DateTime From;
DateTime To;
string[] ChangedProperties;
}
然后将其实例收集在这样的列表中
string[] changes1 = {"A", "B", "C"};
string[] changes2 = {"D"};
string[] changes3 = {"A","B","C","E"};
string[] changes4 = {"A"};
string[] changes5 = {"B"};
string[] changes6 = {"B"};
Change first = new Change()
{
From = new DateTime(2008, 1, 1, 0, 00, 00),
To = new DateTime(2080, 1, 1, 0, 00, 00),
Active = changes1
};
Change second = new Change()
{
From = new DateTime(2008, 1, 1, 0, 00, 00),
To = new DateTime(2010, 1, 1, 0, 00, 00),
Active = changes2
};
Change third = new Change()
{
From = new DateTime(2008, 1, 1, 0, 00, 00),
To = new DateTime(2020, 1, 1, 0, 00, 00),
Active = changes3
};
Change fourth = new Change()
{
From = new DateTime(2005, 1, 1, 0, 00, 00),
To = new DateTime(2008, 1, 1, 0, 00, 00),
Active = changes4
};
Change fifth = new Change()
{
From = new DateTime(2003, 1, 1, 0, 00, 00),
To = new DateTime(2008, 1, 1, 0, 00, 00),
Active = changes5
};
Change sixth = new Change()
{
From = new DateTime(2008, 1, 1, 0, 00, 00),
To = new DateTime(2015, 1, 1, 0, 00, 00),
Active = changes6
};
List<Change> changes = new List<Change>();
changes.Add(first);
changes.Add(second);
changes.Add(third);
changes.Add(fourth);
changes.Add(fifth);
changes.Add(sixth);
我想压缩这个列表,使反映的变化在时间上完全重叠。
例如
first 在日期时间跨度 2008-1-1T00:00:00 到 2080-1-1T00:00:00 中更改属性 {"A", "B", "C"} 但 sixth 在日期时间跨度 2008-1-1T00 中更改属性 B :00:00 至 2015-1-1T00:00:00。第六次变更提供的信息是多余的,因为它完全包含在第一次变更中
first : |---------|
Sixth : |------|
精简列表应该只包含
变化:第一,第二,(仅从第三改变E),第五
这是我目前所拥有的:
【问题讨论】:
-
按开始时间然后结束时间排序,从左到右扫,如果改变
i+1的开始时间>=改变is开始时间&&改变i+1s结束时间is 结束时间,查看这两个属性并根据需要合并。这构成了一个O(n log n)算法。 -
@user1984 你能用一些伪代码形式化它吗?为什么不这样订购?
foreach(var change in changes.OrderByDescending(x => x.To - x.From).ThenByDescending(x => x.Active.Length))我假设大多数都能够适应最大的,并且需要较少的评估? -
@user1984 用户方法不起作用,它会在末尾创建一个额外的 B,由第一个 01/01/2003 00:00:00 01/01/2008 00:00 覆盖: 00 B 01/01/2005 00:00:00 01/01/2008 00:00:00 A 01/01/2008 00:00:00 01/01/2010 00:00:00 D 01/01/2008 00 :00:00 01/01/2015 00:00:00 B
-
您可以为此使用分段树:en.wikipedia.org/wiki/Segment_tree