最快的算法确定范围重叠

发布于 2024-11-14 16:20:27 字数 68 浏览 5 评论 0原文

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

谢谢。

I have two sets of range, each range is a pair of integers indicating start and end. What will be the fastest method to determine if there is any overlap between the two ranges?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

许仙没带伞 2024-11-21 16:20:27

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

If they are both sorted by start you can just inspect the first range in both sets, see if they overlaps and if not move to the next item in the set with the least end offset, rinse and repeat till you find an overlap or you are at the end of one set. This would be O(n) if already sorted, O(n log n) otherwise.

筑梦 2024-11-21 16:20:27

让,

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

创建位向量

最大 (e1, e2} - 最小 {s1, s2}
(或者为了简单起见,假设它是从 0 到 max (e1, e2) )

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

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

这些范围重叠,如果

e1mask & e2mask != 0

let,

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

create bit vector of

max (e1, e2} - min {s1, s2}
(or for simpliciy, assume it is from 0 to max (e1, e2) )

set each range as a set of bits between start and end, i.e

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

these ranges overlap if

e1mask & e2mask != 0
烟沫凡尘 2024-11-21 16:20:27

我会编写以下算法:

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();
}

I would write the following algorithm:

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();
}
半边脸i 2024-11-21 16:20:27
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;
}
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;
}
戏剧牡丹亭 2024-11-21 16:20:27

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

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

Here is a linq query that would return the overlapped points. This would get reduced to a single loop by linq:

from s1 in set1
join s2 in set1
on s1.end < s2.start || s2.end < s1.start
select Tuple.Create(s1,s2);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文