Python 检查范围是否交叉路径
我编写了以下方法来检查范围列表是否有交叉路径。另一种说法是范围不是嵌套的Python 检查范围是否交叉路径,python,algorithm,Python,Algorithm,我编写了以下方法来检查范围列表是否有交叉路径。另一种说法是范围不是嵌套的 def check_ranges(lst): for i in range(len(lst)): for j in range(i+1,len(lst)): # (a,b) and (x,y) are being compared a = lst[i][0] b = lst[i][1] x = lst[j
def check_ranges(lst):
for i in range(len(lst)):
for j in range(i+1,len(lst)):
# (a,b) and (x,y) are being compared
a = lst[i][0]
b = lst[i][1]
x = lst[j][0]
y = lst[j][1]
#both of these conditions mean that they cross
if x < a and b > y:
return True
if x > a and b < y:
return True
return False
它像现在一样工作,但似乎真的效率很低。现在是否有人知道这是一个常见问题,或者是否有更有效的解决方案?您可以进行排序,这至少会将起点按排序顺序排列。然后,您只需要对照前面的条目检查端点;它应该更小:
from itertools import islice
def window(seq, n=2):
"Returns a sliding window (of width n) over data from the iterable"
" s -> (s0,s1,...s[n-1]), (s1,s2,...,sn), ... "
it = iter(seq)
result = tuple(islice(it, n))
if len(result) == n:
yield result
for elem in it:
result = result[1:] + (elem,)
yield result
def check_ranges(lst):
return any(a[1] < b[1] for a, b in window(sorted(lst)))
目前还不完全清楚匹配终点是否会成为一个问题;如果它们不是,那么您可以更改可以排序的
,这将至少将起始点按排序顺序排列。然后,您只需要对照前面的条目检查端点;它应该更小:
from itertools import islice
def window(seq, n=2):
"Returns a sliding window (of width n) over data from the iterable"
" s -> (s0,s1,...s[n-1]), (s1,s2,...,sn), ... "
it = iter(seq)
result = tuple(islice(it, n))
if len(result) == n:
yield result
for elem in it:
result = result[1:] + (elem,)
yield result
def check_ranges(lst):
return any(a[1] < b[1] for a, b in window(sorted(lst)))
目前还不完全清楚匹配终点是否会成为一个问题;如果不是,那么您可以更改我不确定您用于检测“交叉”的算法,但您可以使用理解和:
返回any((x我不确定您用于检测“交叉”的算法,但您可以使用以下方法简化代码:
返回any((xI不确定我是否理解您的预期结果。为什么第一个不失败?(7,16)
是(6,17)
的子集。它是否应该按顺序排列?每个连续范围是否应该是前一个的超集?我不确定我是否理解您的预期结果。为什么第一个不失败?(7,16)
是(6,17)
的子集。它应该是有序的吗?每个连续的范围应该是前一个范围的超集吗?
>>> def check_ranges(lst):
... return any(a[1] < b[1] for a, b in window(sorted(lst)))
...
>>> check_ranges([(7,16),(6,17),(5,18),(4,19)])
False
>>> check_ranges([(5,16),(6,17),(5,18),(4,19)])
True
return any((x<a and b<y or x>a and b<y)
for i,(a,b) in enumerate(lst)
for (x,y) in lst[i:])