寻找字符串数组的最长公共子串

96
阿狸不歌
2019.04.27 23:06* 字数 254

所谓最长公共子串问题是寻找两个或多个已知字符串最长的子串。例如字符串 “ABCD”与“ABCDE”、“FABCDE”的最长公共子串是“ABCD”……

值得注意的是,有些人把最长公共子序列、最长公共前缀与最长公共子串搞混淆了,请特别注意⚠️。

高效算法

《高效算法:竞赛、应试与提高必修128例》中介绍了最长公共子串的算法,不过只是找两个字符串之间的最长公共子串,并没有给出任意个数(此处当然指的是3个或以上)字符串的最长公共子串的求法。

现在用Python试写如下:

def 最长子串(字符串数组):
    子串 = ''
    if len(字符串数组) > 1 and len(字符串数组[0]) > 0:
        for i in range(len(字符串数组[0])):
            for j in range(len(字符串数组[0])-i+1):
                if j > len(子串) and 是否为子串(字符串数组[0][i:i+j], 字符串数组):
                    子串 = 字符串数组[0][i:i+j]
    return 子串

def 是否为子串(鉴定目标, 字符串数组):
    if len(字符串数组) < 1 and len(鉴定目标) < 1:
        return False
    for i in range(len(字符串数组)):
        if 鉴定目标 not in 字符串数组[i]:
            return False
    return True

if __name__ == '__main__':
    测试字符串数组 = ["ABCD", "ABCDE", "FABCDE"]        
    print(最长子串(测试字符串数组))
    # ABCD

最长子串还可以用lamada写法,看起来更加简洁

def lamada最长子串(字符串数组):
    子串 = ''
    if len(字符串数组) > 1 and len(字符串数组[0]) > 0:
        for i in range(len(字符串数组[0])):
            for j in range(len(字符串数组[0])-i+1):
                if j > len(子串) and all(字符串数组[0][i:i+j] in 元素 for 元素 in 字符串数组):
                    子串 = 字符串数组[0][i:i+j]
    return 子串

if __name__ == '__main__':
    测试字符串数组 = ["ABCD", "ABCDE", "FABCDE", "1ABCDF"]
    print(lamada最长子串(测试字符串数组))
    # ABCD

这个方法的复杂度是 O(n1 x n1 x (n1 + ... + nK)) , 如果字符串不复杂,还是可以一用的😄。

算法
Gupao