【问题标题】:Computing where the overlap is计算重叠的位置
【发布时间】:2013-03-08 14:40:05
【问题描述】:

如果您有两对值,开始和结束 - 您如何计算它们的重叠位置?

即如果开始和结束值对是

[10, 20], [15, 20]

在这种情况下,compute_overlap((15,20),(10,20)) 应该返回 (15,20),因为那是重叠的地方。

最好的方法是什么?

【问题讨论】:

标签: python algorithm


【解决方案1】:

如果您的间隔是a, bc, d,即

(a, b), (c, d) = [10, 20], [15, 20]

那么重叠区间为

x, y = max(a, c), min(b, d)
if x > y:  # no overlap
    x, y = None, None

重叠量为y - xy - x + 1,取决于您的区间是闭合的还是half-closed(此处假设为整数)。

【讨论】:

  • 重叠量也可以是y - x - 1,如果第一个区间在高端是半封闭的,而第二个区间在低端是半封闭的,例如[1,5)(3,7].
  • @G.Bach: 是的,但是在低端半封闭的区间,更不用说区间类型的混合,有点“深奥”——如果我不得不使用它们,我'如果可能的话,会将它们转换为高端的半封闭,然后进行任何计算。
  • @larsmans 好吧,如果你无论如何都要转换,如果这些是整数的区间,你也可以将它们全部转换为闭区间。但这当然是在我这边挑剔,您的解决方案优雅地解决了发布的问题,而旁白只是对可能不适用于该问题的极端案例的注释。
  • 如何找到这两个范围之间的 %age 重叠? (a, b), (c, d) = [10,17], [16, 20] 应该给我 2/5 = 40% 的重叠百分比
【解决方案2】:

使用zip 将起点和终点组合在一起。然后用max求最大起点,min求最小终点:

>>> def compute_overlap(pairs):
...     starts, ends = zip(*pairs)
...     return max(starts), min(ends)
... 
>>> compute_overlap(([10, 20], [15,20]))
(15, 20)

【讨论】:

    【解决方案3】:

    假设您有一个可迭代对象并且您想要计算相邻项的重叠...

    您需要“成对”生成元素。通常,这很简单:

    seq = [[10, 20], [15, 20]]
    for lower,upper in zip(seq,seq[1:]):
        if upper[0] > lower[1]:
            print lower[1],upper[0] 
        else:
            print None, None
    

    不幸的是,切片仅适用于序列,而不适用于任意迭代。不过不难概括:

    def funny_zip(seq):
        iseq = iter(seq)
        current = next(iseq):
        for item in iseq:
            yield current,item
            current = item
    

    现在你可以使用:

    for lower,upper in funny_zip(seq):
        ...
    

    【讨论】:

    • @Junuxx -- 更新了我的答案以说明它不起作用的情况。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-20
    • 1970-01-01
    相关资源
    最近更新 更多