所谓最长公共子串问题是寻找两个或多个已知字符串最长的子串。例如字符串 “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)) , 如果字符串不复杂,还是可以一用的😄。
网友评论