【问题标题】:c# + check gaps and overlaps in list of tuplesc# + 检查元组列表中的间隙和重叠
【发布时间】:2012-01-20 21:39:36
【问题描述】:

我有元组列表。每个元组都有一个最小值和最大值。

我想检查提供的列表中是否有任何范围缺失或重叠。

这是定义。

 List<Tuple<int, int>> sequences = new List<Tuple<int, int>>();

示例:

1. sequences.Add(new Tuple<int, int>(1, 10));
   sequences.Add(new Tuple<int, int>(11, 20));
   This is fine

2. sequences.Add(new Tuple<int, int>(1, 10));
   sequences.Add(new Tuple<int, int>(13, 20));
   This there are gaps in the sequence

3. sequences.Add(new Tuple<int, int>(1, 10));
   sequences.Add(new Tuple<int, int>(10, 20));
   This is an overlapping scenario

目前我在做

  int minrange = 1;
   int maxrange = 20;
   var gaps = Enumerable.Range(minrange, maxrange).Where(i => sequences.All(t => t.Item1 > i || t.Item2 < i));
   var overlapping = Enumerable.Range(minrange, maxrange).Where(i => sequences.Count(t => t.Item1 <= i && t.Item2 >= i) > 1);

当序列的值为:

minrange = 1;
maxrange = 2097152;    
sequences.Add(new Tuple<int, int>(1, 10));
    sequences.Add(new Tuple<int, int>(11, 20));
    sequences.Add(new Tuple<int, int>(21, 2097152));

在这种情况下,我的 var gaps 返回一个不应该的计数,因为它们是没有间隙或重叠的有效范围

  1. 这是验证它们的正确方法吗?
  2. 我做错了什么?

【问题讨论】:

  • 您是否需要知道是否有间隙/重叠,或者您是否需要计算这样的数量?
  • 根据您的需要,您可能会发现像 en.wikipedia.org/wiki/Interval_tree 这样的数据结构很有用。
  • @Nate:这正是我想用代码实现的 :)

标签: c# tuples


【解决方案1】:

如果您只需要一个是或否的答案,我相信以下问题可以回答:

var overlaps =
   (from s1 in sequences from s2 in sequences
    where s1.Item2 >= s2.Item1 && s1.Item1 < s2.Item1 select s1).Any();

var gaps =
    (from s1 in sequences where s1.Item1 > 1 select s1.Item1).Any(
          i => !sequences.Any(
                j => j.Item2 >= i-1&&j.Item1 < i));

希望您可以相当轻松地“阅读”第一个查询。第二个花了我一些努力,但有效地询问“是否有任何元组(除了从 1 开始的元组)其最低值 1 未被集合中的另一个元组覆盖?”

但是,如果您的集合很大,我会在 SQL 中而不是在 C# 中执行此操作 - 提出此类“基于集合”的问题感觉更自然。

【讨论】:

    【解决方案2】:

    我尚未对此进行测试,但要找到差距,您可以执行以下操作:

    int lastMax = sequences[0].Item2;
    var gaps = sequences.Skip(1).Where(item =>
        {
            bool res = lastMax + 1 < item.Item1;
            lastMax = item.Item2;
            return res;
        });
    

    并找到重叠的项目:

    int lastMax = sequences[0].Item2;
    var overlaps = sequences.Skip(1).Where(item =>
        {
            bool res = lastMax >= item.Item1;
            lastMax = item.Item2;
            return res;
        });
    

    这两个示例都假定您的列表已按 Item1 排序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多