题目:用Python实现查找两个字符串str1、str2中的最长公共子串。
输入描述:
输入两个字符串
输出描述:
输出最长公共字符串。
示例1
输入
acbcbcef
abcbced
输出
bcbce
示例2
输入
dfxjasfdfhaasdfhk
dfjasf456789aasdfh0987dfhaas
输出
aasdfh,dfhaas
题解方法一般有如下三种:
1、两个字符串str1、str2,从其中较短一个字符串截取由大到小的子串,和较长一个字符串匹配,依次循环查找。
#以其中较短的字符串,从长到短依次循环匹配查找
str1=input()
str2=input()
str1,str2=(str2,str1) if len(str1)>len(str2) else (str1,str2)
f=[]
for i in range(len(str1),0,-1):
for j in range(len(str1)+1-i):
e=str1[j:j+i]
if e in str2:
f.append(e)
if f:
break
f1=",".join(f)
print(f1)
2、矩阵算法思路:把两个字符串分别以行和列组成一个二维矩阵;比较二维矩阵中每个点对应行列字符中否相等,相等的话值设置为1,否则设置为0;通过查找出值为1的最长对角线就能找到最长公共子串。针对于上面的两个字符串我们可以得到的二维矩阵如下:
从上图可以看到,str1和str2共有5个公共子串,但最长的公共子串长度为5。
为了进一步优化算法的效率,我们可以再计算某个二维矩阵的值的时候顺便计算出来当前最长的公共子串的长度,即某个二维矩阵元素的值由M[i][j]=1演变为M[i][j]=1 +M[i-1][j-1],这样就避免了后续查找对角线长度的操作了。修改后的二维矩阵如下:
str1="acbcbcef"
str2="abcbced"
M= [[0 for i in range(len(str1)+1)] for i in range(len(str2)+1)]
xmax=0
xindex=[]
for i in range(1,len(str2)+1):
for j in range(1,len(str1)+1):
if (str2[i-1]==str1[j-1]):
M[i][j]=M[i-1][j-1]+1
if M[i][j] > xmax:
xmax=M[i][j]
xindex=[(i,j)]
elif M[i][j]==xmax:
xindex.append((i,j))
lcstr=",".join([str1[i-xmax:i] for i in xindex])
print(lcstr)
注意:因为使用 list*n 来扩张多维列表时,实际采用的是浅拷贝,会造成修改问题。这儿构造二维零矩阵M时,不能用 M =[[0]*(len(str1)+1)]*(len(str2)+1)
3、