最长公共子串与最长公共子序列
Posted 光彩照人
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最长公共子串与最长公共子序列相关的知识,希望对你有一定的参考价值。
一、最长公共子串(Longest Common Substring)
遍历的时候用一个二维数组存储相应位置的信息,如果两个子串1与子串2相应位置相等:则看各自前一个位置是否相等,相等则该位置值B[i][j]=B[i-1][j-1]+1,不相等则置为1。如果两个子串1与子串2相应位置不相等,则B[i][j]=0。如下:
代码如下:
def longestSub(str1,str2): s1=list(str1) s2=list(str2) B=[([0]*len(s2)) for i in range(len(s1))] maxLen=0 for i in range(len(s1)): for j in range(len(s2)): if s1[i]==s2[j]: if i-1>=0 and j-1>=0: B[i][j]=B[i-1][j-1]+1 if B[i][j]>maxLen: maxLen=B[i][j] else: B[i][j]=1 else: B[i][j] = 0 print(B) return maxLen s1="asdfas" s2="werasdfaswer" print(longestSub(s1,s2))
二、最长公共子序列(Longest Common SubSequence)
跟最长公共子串一样遍历,用一个二维数组保存相应位置的信息,最长公共子序列基于这样一个思想:
1.如果子串1与子串2当前位置相等,则说明最大公共子序列等于去掉当前位置各自前面子串的最大公共子序列值+1,即B[i][j]=B[i-1][j-1]+1
2.如果子串1与子串2当前位置不相等,则目前为止的最大公共子序列为: {S1减去当前元素} 与 S2 的LCS, {S2减去当前元素} 与 S1 的LCS 中的最大的那个序列。注:S1为子串1遍历到当前位置为止的字符串,S2为子串2遍历到当前为止的字符串。
def longestSubSequence(str1,str2): s1 = list(str1) s2 = list(str2) B = [([0] * len(s2)) for i in range(len(s1))] maxlen=0 for i in range(len(s1)): for j in range(len(s2)): if s1[i]==s2[j]: if i>0 and j>0: B[i][j]=B[i-1][j-1]+1
#注意边界条件,没有B[i-1][j-1],就置为1,因为字符相等了肯定得为1了。 else: B[i][j]=1 if B[i][j]>maxlen: maxlen=B[i][j] else: if i>0 and j>0: B[i][j]=max(B[i-1][j],B[i][j-1])
#也是注意边界条件,一个减去1个字符,为空了,另一个字符串的最大子序列就是最大子序列值了。 if i>0 and j==0: B[i][j]=B[i-1][j]
#同上 if i==0 and j>0: B[i][j]=B[i][j-1]
#起始位置,B[0][0]的位置不相等,自然为0了 if i==0 and j==0: B[i][j]=0 return maxlen
以上是关于最长公共子串与最长公共子序列的主要内容,如果未能解决你的问题,请参考以下文章