最长公共子串与最长公共子序列

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

 

以上是关于最长公共子串与最长公共子序列的主要内容,如果未能解决你的问题,请参考以下文章

C语言实现最长公共子串与最长公共子序列

最长公共子串与最长公共子序列之间的关系

最长公共子串和最长公共子序列

动态规划——最长公共子序列与最长公共子串 (含Python实现代码)

最长公共子串

算法图解:动态规划之最长公共子串,最长公共子序列