将更改列表压缩为较小的列表

Posted

技术标签:

【中文标题】将更改列表压缩为较小的列表【英文标题】:Condensing list of changes to a smaller list 【发布时间】: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),第五

这是我目前所拥有的:

https://dotnetfiddle.net/9ytlh7

【问题讨论】:

按开始时间然后结束时间排序,从左到右扫,如果改变i+1的开始时间>=改变is开始时间&amp;&amp;改变i+1s结束时间is 结束时间,查看这两个属性并根据需要合并。这构成了一个O(n log n) 算法。 @user1984 你能用一些伪代码形式化它吗?为什么不这样订购? foreach(var change in changes.OrderByDescending(x =&gt; x.To - x.From).ThenByDescending(x =&gt; 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 【参考方案1】:

这就是我最终这样做的方式......

https://dotnetfiddle.net/OliMgt

不确定这是否有效?

【讨论】:

以上是关于将更改列表压缩为较小的列表的主要内容,如果未能解决你的问题,请参考以下文章

尝试将列表拆分为较小的列表时出错

将列表拆分为较小的列表(分成两半)

python – 将列表拆分为较小的列表

c#如何将2D数组拆分为较小的2D数组(块)列表?

如何将 mysqldump 的输出拆分为较小的文件?

如何将大数组拆分为较小的数组?