Python 如何在一组排序数组中查找最大的连续重叠区域

Python 如何在一组排序数组中查找最大的连续重叠区域,python,arrays,numpy,Python,Arrays,Numpy,给定有序1D数组的元组(arr1,arr2,arr3,),哪种方法是获得最小/最大索引的元组((min1,max1),(min2,max2),(min3,max3),),以便数组跨越最大的公共范围 我的意思是 min(arr[min1], arr2[min2], arr3[min3]) > max(arr1[min1-1], arr2[min2-1], arr3[min3-1]) 及 但是,这两个答案似乎都适用于我提出的问题,因此我不确定是否只选择其中一个作为“正确”-我应该怎么做?我确

给定有序1D数组的元组
(arr1,arr2,arr3,)
,哪种方法是获得最小/最大索引的元组
((min1,max1),(min2,max2),(min3,max3),)
,以便数组跨越最大的公共范围

我的意思是

min(arr[min1], arr2[min2], arr3[min3]) > max(arr1[min1-1], arr2[min2-1], arr3[min3-1])


但是,这两个答案似乎都适用于我提出的问题,因此我不确定是否只选择其中一个作为“正确”-我应该怎么做?

我确定有不同的方法来实现这一点,我将使用算法遍历两个阵列,跟踪重叠区域。如果您不熟悉这个想法,请看一看,希望在这个想法和代码之间可以清楚地看到它是如何工作的

def find_overlap(a, b):
    i = 0
    j = 0
    len_a = len(a)
    len_b = len(b)
    in_overlap = False
    best_count = 0
    best_start = (-1, -1)
    best_end = (-1, -1)

    while i < len_a and j < len_b:

        if a[i] == b[j]:
            if in_overlap:
                # Keep track of the length of the overlapping region
                count += 1
            else:
                # This is a new overlapping region, set count to 1 record start
                in_overlap = True
                count = 1
                start = (i, j)
            # Step indicies
            i += 1
            j += 1
            end = (i, j)
            if count > best_count:
                # Is this the longest overlapping region so far?
                best_count = count
                best_start = start
                best_end = end
        # If not in a an overlapping region, only step one index
        elif a[i] < b[j]:
            in_overlap = False
            i += 1
        elif b[j] < a[i]:
            in_overlap = False
            j += 1
        else:
            # This should never happen
            raise
    # End of loop

    return best_start, best_end
def find_重叠(a,b):
i=0
j=0
len_a=len(a)
len_b=len(b)
in_重叠=错误
最佳计数=0
最佳开始=(-1,-1)
最佳端=(-1,-1)
而i最佳计数:
#这是迄今为止最长的重叠区域吗?
最佳计数=计数
最佳开始=开始
最佳结束=结束
#如果不在重叠区域中,则只执行第一步索引
如果a[i]

请注意,这里的end是在python约定中返回的,所以如果
a=[0,1,2]
b=[0,1,4]
start=(0,0)
end=(2,2)
,我认为您正在寻找一种解决这种情况的特殊方法。虽然这个问题可以用后缀树或动态规划来解决,但排序“字符串”的特殊情况更容易解决

这里的代码,我认为会给你你想要的值。它的单个参数是一个排序序列。它的返回值是包含每个内部序列的2元组的列表。元组值是序列之间最长公共子字符串的切片索引。请注意,如果没有公共子字符串,元组将全部为
(0,0)
,这将导致空片段(我认为这是正确的,因为空片段将彼此相等!)

守则:

def longest_common_substring_sorted(sequences):
    l = len(sequences)
    current_indexes = [0]*l
    current_substring_length = 0
    current_substring_starts = [0]*l
    longest_substring_length = 0
    longest_substring_starts = current_substring_starts

    while all(index < len(sequence) for index, sequence
              in zip(current_indexes, sequences)):
        m = min(sequence[index] for index, sequence
                in zip(current_indexes, sequences))
        common = True
        for i in range(l):
            if sequences[i][current_indexes[i]] == m:
                current_indexes[i] += 1
            else:
                common = False

        if common:
            current_substring_length += 1
        else:
            if current_substring_length > longest_substring_length:
                longest_substring_length = current_substring_length
                longest_substring_starts = current_substring_starts
            current_substring_length = 0
            current_substring_starts = list(current_indexes)

    if current_substring_length > longest_substring_length:
        longest_substring_length = current_substring_length
        longest_substring_starts = current_substring_starts

    return [(i, i+longest_substring_length)
            for i in longest_substring_starts]

我很抱歉没有对代码进行很好的注释。该算法有点类似于mergesort的合并步骤。基本上,它跟踪每个序列的索引。当它迭代时,它会增加与最小值相等的值对应的所有索引。如果所有列表中的当前值相等(等于最小值,因此彼此相等),则它知道该值位于所有列表公用的子字符串中。当一个子串结束时,将对照迄今为止找到的最长子串进行检查。

。。。这并不是说您在寻找一组排序整数数组中最大的连续重叠区域,而是无法用简单的英语表达出来。这是一组排序数组,大部分是浮点数组。我相应地更新了问题。你对arange(12,step=2)和arange(3,8)有什么期望?如果我理解正确:我建议使用“窗口”而不是“范围”。考虑到这两个条件,您正在寻找数组相对对齐的最大窗口:窗口顶行中的数字必须大于上面的所有数字,小于下面的所有数字+相同,反之亦然,用于窗口底行。。。这是对的吗?@TheodrosZelleke感谢你帮助我提出问题;)但现在我想你把它搞混了。根据我的理解,第一行的数字必须大于下面的所有数字,小于上面的所有数字,反之亦然。这就是你想说的吗?否则,我不明白你们所说的“窗口顶行”到底是什么意思。
def find_overlap(a, b):
    i = 0
    j = 0
    len_a = len(a)
    len_b = len(b)
    in_overlap = False
    best_count = 0
    best_start = (-1, -1)
    best_end = (-1, -1)

    while i < len_a and j < len_b:

        if a[i] == b[j]:
            if in_overlap:
                # Keep track of the length of the overlapping region
                count += 1
            else:
                # This is a new overlapping region, set count to 1 record start
                in_overlap = True
                count = 1
                start = (i, j)
            # Step indicies
            i += 1
            j += 1
            end = (i, j)
            if count > best_count:
                # Is this the longest overlapping region so far?
                best_count = count
                best_start = start
                best_end = end
        # If not in a an overlapping region, only step one index
        elif a[i] < b[j]:
            in_overlap = False
            i += 1
        elif b[j] < a[i]:
            in_overlap = False
            j += 1
        else:
            # This should never happen
            raise
    # End of loop

    return best_start, best_end
def longest_common_substring_sorted(sequences):
    l = len(sequences)
    current_indexes = [0]*l
    current_substring_length = 0
    current_substring_starts = [0]*l
    longest_substring_length = 0
    longest_substring_starts = current_substring_starts

    while all(index < len(sequence) for index, sequence
              in zip(current_indexes, sequences)):
        m = min(sequence[index] for index, sequence
                in zip(current_indexes, sequences))
        common = True
        for i in range(l):
            if sequences[i][current_indexes[i]] == m:
                current_indexes[i] += 1
            else:
                common = False

        if common:
            current_substring_length += 1
        else:
            if current_substring_length > longest_substring_length:
                longest_substring_length = current_substring_length
                longest_substring_starts = current_substring_starts
            current_substring_length = 0
            current_substring_starts = list(current_indexes)

    if current_substring_length > longest_substring_length:
        longest_substring_length = current_substring_length
        longest_substring_starts = current_substring_starts

    return [(i, i+longest_substring_length)
            for i in longest_substring_starts]
>>> a=[1,2,3,4,5,6]
>>> b=[1,2,3,5,6,7]
>>> c=[3,4,5,6,7,8]
>>> longest_common_substring_sorted((a,b,c))
[(4, 6), (3, 5), (2, 4)]