假设我有一个完整的元组列表,表示“从”和“到”时间:
tuples = [ (0, 5), (5, 10), (10, 15), (15,20) ]
我希望能够检索与给定元组重叠的元组列表:
searchTuple = (3,11)
result = findOverlap(tuples, searchTuple)
此代码应返回以下列表:
[ (0, 5), (5, 10), (10, 15) ]
虽然(16,22)的searchTuple应该只返回最后一个元组(15,20)
对此检索进行编码的最有效方法是什么?我尝试了各种各样的东西,但我无法让算法正常工作。我想到了以下不同的“重叠”,我有兴趣捕捉:
a) tuple_min < find_min AND tuple_max > find_max
search tuple -> | |
|----------------| the search tuple is entirely contained
b) tuple_min > find_min AND tuple_max > find_max
| |
|----------------| the left part of the tuple overlaps
c) tuple_min < find_min AND tuple_max < find_max
| |
|----------------| the right part of the tuple overlaps
然而,实施此结果后我得到的结果最终给我错误的结果......我的想法在哪里错了?
答案 0 :(得分:5)
您还没有涵盖搜索元组完全包含与之进行比较的当前元组的情况。在你的情况下,说(3,11)对(5,10)
答案 1 :(得分:3)
回答我自己的问题,因为我找到了一个优雅的解决方案:
tuples = [(0,5), (5,10), (10,15), (15,20)]
def overlap(tuples, search):
res = []
for t in tuples:
if(t[1]>search[0] and t[0]<search[1]):
res.append(t)
return res
search = (1,11)
print overlap(tuples, search)
按预期返回:
[(0, 5), (5, 10), (10, 15)]
答案 2 :(得分:2)
这是你能写的最愚蠢的代码:
def findOverlap(tuples, searchTuple):
result = []
for p in tuples:
if (p[0] <= searchTuple[0] and searchTuple[0] <p[1]) or \
(p[0] < searchTuple[1] and p[1] >searchTuple[1]) or \
(p[0] < searchTuple[0] and p[1] searchTuple[1]):
result.append(p)
if (p[0] > searchTuple[1]):
break
我希望我没有弄错指数! 如果您对元组进行排序,则可以通过更智能的搜索来提高代码性能。 几年前,当我试图学习算法时,我遇到了类似的问题。所以我想这是一个流行的问题类型,你可以通过谷歌搜索找到有效的代码
答案 3 :(得分:2)
快速和脏的列表理解:
>>> t = [ (0, 5), (5, 10), (10, 15), (15,20) ]
>>> o = (3,11)
>>> [(i[0],i[1]) for i in t if i[0] >= o[0] and i[0] <= o[1] or i[1] >= o[0] and i[1] <= o[1]]
#returns:
[(0, 5), (5, 10), (10, 15)]
>>> o = (16,22)
#returns
[(15, 20)]
答案 4 :(得分:1)
这种方法对初学者友好,应该可以解决问题
def findOverlap(tuples, searchTuple):
result=[]
for tuple in tuples:
if searchTuple[0] in range(tuple[0],tuple[1]): #search for the first value
result.append(tuple)
continue
if len(result)>0 and searchTuple[1] in range(tuple[0],tuple[1]): #search for the last value
result.append(tuple)
break
if len(result)>0:
result.append(tuple) #add all elements between first and last
return result
range(tuple[0],tuple[1])
只返回从一个到另一个的所有数字,因此如果查看(5,10)
元组,它将返回[5,6,7,8,9,10]
然后searchTuple[0] in range(tuple[0],tuple[1])
检查searchTuple中的第一个元素是否在该范围内。
result.append(tuple)
将元组添加到从方法返回的事物列表中。
其余部分是循环操作和格式化内容。
答案 5 :(得分:1)
这是我的解决方案:
tuples = [ (0, 5), (5, 10), (10, 15), (15,20) ]
searchTuple = (3,11)
result = [tInnerRange for tInnerRange in tuples if searchTuple[0] >= tInnerRange[0] and searchTuple[0] < tInnerRange[1] or searchTuple[1] > tInnerRange[0] and searchTuple[1] <= tInnerRange[1] or searchTuple[0] <= tInnerRange[0] and searchTuple[1] >= tInnerRange[1]]
=============================================== =================================
以下是'searchTuple'的各种值的一些示例输出:
# In this case, 'searchTuple' is overlaping 2 ranges, and bounds don't coincide
tuples = [ (0, 5), (5, 10), (10, 15), (15,20) ]
searchTuple = (8,11)
result = [tInnerRange for tInnerRange in tuples if searchTuple[0] >= tInnerRange[0] and searchTuple[0] < tInnerRange[1] or searchTuple[1] > tInnerRange[0] and searchTuple[1] <= tInnerRange[1] or searchTuple[0] <= tInnerRange[0] and searchTuple[1] >= tInnerRange[1]]
print(result)
====> [(5, 10), (10, 15)]
&安培;
# In this case, 'searchTuple' is overlaping 3 ranges, and bounds don't coincide. Also, lower bounds is 'out-of-bound' and negative
tuples = [ (0, 5), (5, 10), (10, 15), (15,20) ]
searchTuple = (-3,11)
result = [tInnerRange for tInnerRange in tuples if searchTuple[0] >= tInnerRange[0] and searchTuple[0] < tInnerRange[1] or searchTuple[1] > tInnerRange[0] and searchTuple[1] <= tInnerRange[1] or searchTuple[0] <= tInnerRange[0] and searchTuple[1] >= tInnerRange[1]]
print(result)
====> [(0, 5), (5, 10), (10, 15)]
&安培;
# In this case, 'searchTuple' is overlaping 2 ranges, lower bound coincides.
tuples = [ (0, 5), (5, 10), (10, 15), (15,20) ]
searchTuple = (5,11)
result = [tInnerRange for tInnerRange in tuples if searchTuple[0] >= tInnerRange[0] and searchTuple[0] < tInnerRange[1] or searchTuple[1] > tInnerRange[0] and searchTuple[1] <= tInnerRange[1] or searchTuple[0] <= tInnerRange[0] and searchTuple[1] >= tInnerRange[1]]
print(result)
====> [(5, 10), (10, 15)]
&安培;
# In this case, 'searchTuple' is overlaping 1 ranges, both bounds coincide.
tuples = [ (0, 5), (5, 10), (10, 15), (15,20) ]
searchTuple = (5,10)
result = [tInnerRange for tInnerRange in tuples if searchTuple[0] >= tInnerRange[0] and searchTuple[0] < tInnerRange[1] or searchTuple[1] > tInnerRange[0] and searchTuple[1] <= tInnerRange[1] or searchTuple[0] <= tInnerRange[0] and searchTuple[1] >= tInnerRange[1]]
print(result)
====> [(5, 10)]
&安培;
# In this case, 'searchTuple' is overlaping 2 ranges, and upper bound coincides.
tuples = [ (0, 5), (5, 10), (10, 15), (15,20) ]
searchTuple = (3,10)
result = [tInnerRange for tInnerRange in tuples if searchTuple[0] >= tInnerRange[0] and searchTuple[0] < tInnerRange[1] or searchTuple[1] > tInnerRange[0] and searchTuple[1] <= tInnerRange[1] or searchTuple[0] <= tInnerRange[0] and searchTuple[1] >= tInnerRange[1]]
print(result)
====> [(0, 5), (5, 10)]
&安培;
# In this case, 'searchTuple' is overlaping 2 ranges, and lower bound coincides. Also, upper bounds is 'out-of-bound'.
tuples = [ (0, 5), (5, 10), (10, 15), (15,20) ]
searchTuple = (10,49)
result = [tInnerRange for tInnerRange in tuples if searchTuple[0] >= tInnerRange[0] and searchTuple[0] < tInnerRange[1] or searchTuple[1] > tInnerRange[0] and searchTuple[1] <= tInnerRange[1] or searchTuple[0] <= tInnerRange[0] and searchTuple[1] >= tInnerRange[1]]
print(result)
====> [(10, 15), (15, 20)]
&安培;
# In this case, 'searchTuple' is overlaping 0 ranges has both bounds are 'out-of-bound'.
tuples = [ (0, 5), (5, 10), (10, 15), (15,20) ]
searchTuple = (25,49)
result = [tInnerRange for tInnerRange in tuples if searchTuple[0] >= tInnerRange[0] and searchTuple[0] < tInnerRange[1] or searchTuple[1] > tInnerRange[0] and searchTuple[1] <= tInnerRange[1] or searchTuple[0] <= tInnerRange[0] and searchTuple[1] >= tInnerRange[1]]
print(result)
====> []