【问题标题】: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

标签: c# algorithm


【解决方案1】:

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

https://dotnetfiddle.net/OliMgt

不确定这是否有效?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-04
    • 2020-07-16
    • 1970-01-01
    • 2012-07-12
    • 1970-01-01
    • 2010-11-07
    • 2012-11-04
    • 1970-01-01
    相关资源
    最近更新 更多