用Python实现查找两个字符串a,b中的最长公共子串

题目:用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、

  • 12
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

楠溪居士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值