将重叠的时间范围及其权重合并在一起

时间:2019-10-23 06:51:32

标签: c# .net algorithm

我有一个DateRange模型,该模型位于以下位置:

public class DateRange
{
    public DateTime start { get; set; }
    public DateTime end { get; set; }
    public int weight { get; set; }
}

以下是列表:

[
  {
    "start": 1, "end": 3, "weight": 1
  },
  {
    "start": 10, "end": 20, "weight": 3
  },
  {
    "start": 12, "end": 15, "weight": 2
  },
  {
    "start": 22, "end": 26, "weight": 7
  },
  {
    "start": 25, "end": 30, "weight": 4
  }
]

我想合并列表。 合并列表重叠时间范围的权重必须加在一起。

结果样本:

[
  {
    "start": 1, "end": 3, "weight": 1
  },
  {
    "start": 10, "end": 12, "weight": 3
  },
  {
    "start": 12, "end": 15, "weight": 5
  },
  {
    "start": 15, "end": 20, "weight": 3
  },
  {
    "start": 22, "end": 25, "weight": 7
  },
  {
    "start": 25, "end": 26, "weight": 11
  },
  {
    "start": 26, "end": 30, "weight": 4
  }
]

1 个答案:

答案 0 :(得分:0)

public class DataComparer : IComparer<Data>
{
    public int Compare(Data d1, Data d2)
    {
        if (d1.start == d2.start)
        {
            return d1.end.CompareTo(d2.end);
        }
        return d1.start.CompareTo(d2.start);
    }
}
public List<Data> resolveConflicts(List<Data> list)
{
    list.Sort(new DataComparer());
    for (int i = 0; i < list.Count - 1; i++)
    {
        var current = list[i];
        var next = list[i + 1];
        if (i > 1)
        {
            var pre = list[i - 1];
            if (pre.end == current.start && pre.weight == current.weight) // 10 - 12 > 12 - 14
            {
                i = i - 2;
                continue;
            }
        }
        if (next.start < current.end)
        {
            if (next.end < current.end) //10 - 20 > 12 - 15
            {
                list.Add(new Data(next.end, current.end, current.weight));
                list.Sort(new DataComparer());

                current.end = next.start;
                next.weight += current.weight;
                i--;
            }
            else if (next.end == current.end) // 1 - 5 // 2 - 5
            {
                next.weight += current.weight;
                if (current.start == next.start)
                {
                    list.Remove(current);
                    i--;
                }
                else
                {
                    current.end = next.start;
                }
            }
            else if (next.end > current.end) //1 - 5 > 4 - 6
            {
                if (next.start == current.start) // 1 - 6 > 1 - 7
                {
                    current.weight += next.weight;
                    next.start = current.end;

                    list.Sort(new DataComparer());
                    i--;
                }
                else
                {
                    list.Add(new Data(next.start, current.end, next.weight + current.weight));

                    var temp = current.end;
                    current.end = next.start;
                    next.start = temp;

                    list.Sort(new DataComparer());
                    i--;
                    continue;
                }
            }
        }
        else if (next.start == current.end && next.weight == current.weight) // 1 - 5 > 5 - 7
        {
            current.end = next.end;
            list.Remove(next);
            i--;
        }

    }

    return list;
}