最快的算法确定范围重叠

时间:2011-06-08 18:55:26

标签: c# .net algorithm overlap

我有两组范围,每个范围是一对整数,表示开始和结束。确定两个范围之间是否存在重叠的最快方法是什么?

感谢。

5 个答案:

答案 0 :(得分:8)

如果它们都是按开始排序,你可以检查两组中的第一个范围,看看它们是否重叠,如果没有移动到具有最小结束偏移的集合中的下一个项目,则冲洗并重复直到找到重叠或者你是一组的结尾。如果已经排序,则为O(n),否则为O(n log n)。

答案 1 :(得分:3)

让,

  

r1 = {s1,e1}
  r2 = {s2,e2}

创建

的位向量
  

max(e1,e2} - min {s1,s2}
  (或者简单地说,假设它从0到最大(e1,e2))

将每个范围设置为开始和结束之间的一组位,即

e1mask = ((0x1<<(e1-s1))-1)<<s1;
e2mask = ((0x1<<(e2-s2))-1)<<s2;

这些范围重叠,如果

e1mask & e2mask != 0

答案 2 :(得分:1)

我会写下面的算法:

bool Overlap(int s, int e, int s1, int e1) 
{
  if(s > s1 && s < e1)
     return true;
  if(s1 > s && s1 < e)
     return true;
  return false;
}
int[] overlaps(Range[] ranges)
{
   List<int> res = new List<int>();
   foreach(Range r in ranges)
   {
       foreach(Range rr in ranges)
       {
            if(Overlap(r.start, r.end, rr.start, rr.end))
                 res.add(r.start);
       }
   }
   return res.ToArray();
}

答案 3 :(得分:1)

private static bool Overlap(Range a, Range b)
{
    if (a.Start >= b.Start && a.Start <= b.End)
    {
        return true;
    }

    if (b.Start >= a.Start && b.Start <= a.End)
    {
        return true;
    }

    return false;
}

private static bool CheckOverlap(List<Range> ranges)
{
    for (var i = 0; i < ranges.Count - 1; i++)
    {
        for (var j = i + 1; j < ranges.Count; j++)
        {
            if (Overlap(ranges[i], ranges[j]))
            {
                return false;
            }
        }
    }

    return true;
}

答案 4 :(得分:0)

这是一个返回重叠点的linq查询。这将由linq减少为单个循环:

from s1 in set1
join s2 in set1
on s1.end < s2.start || s2.end < s1.start
select Tuple.Create(s1,s2);