最长公共子串和子序列的Python实现,带图示。

使用矩阵来记录两个子串之间各个字符之间的对应关系。

最长子串:矩阵中数字最大的就是最长子串的长度。若对应位置字符相同,则c[i][j] = c[i-1][j-1] + 1

 1 def longSubStr(str1,str2):
 2     len1 = len(str1)
 3     len2 = len(str2)
 4     longest,start1,start2 = 0,0,0
 5     c = [[0 for i in range(len2+1)]for i in range(len1+1)]
 6     for i in range(len1+1):
 7         for j in range(len2+1):
 8             if i == 0 or j == 0:
 9                 c[i][j] = 0
10             elif str1[i-1] == str2[j-1]:
11                 c[i][j] = c[i-1][j-1]+1
12             else:
13                 c[i][j] = 0
14             if (longest < c[i][j]):
15                 longest = c[i][j]
16                 start1 = i-longest
17                 start2 = j-longest
18
19     return str1[start1:start1+longest],start1,start2

最长子序列:若对应位置字符相同,则c[i][j] = c[i-1][j-1] + 1,若不同,则max(c[i][j-1],c[i-1][j]).

 1 def printLcs(flag,a,i,j):
 2     if i==0 or j==0:
 3         return
 4     if flag[i][j]==‘OK‘:
 5         printLcs(flag,a,i-1,j-1)
 6         print a[i-1],
 7     elif flag[i][j]==‘Left‘:
 8         printLcs(flag,a,i,j-1)
 9     else:
10         printLcs(flag,a,i-1,j)
11
12 def longSubSeq(str1,str2):
13     len1 = len(str1)
14     len2 = len(str2)
15     longest = 0
16     c = [[0 for i in range(len2+1)]for i in range(len1+1)]
17     flag = [[0 for i in range(len2+1)]for i in range(len1+1)]
18     for i in range(len1+1):
19         for j in range(len2+1):
20             if i == 0 or j == 0:
21                 c[i][j] = 0
22             elif str1[i-1] == str2[j-1]:
23                 c[i][j] = c[i-1][j-1]+1
24                 flag[i][j] = ‘OK‘
25                 longest = max(longest,c[i][j])
26             elif c[i][j-1] > c[i-1][j]:
27                 c[i][j] =c[i][j-1]
28                 flag[i][j] = ‘Left‘
29             else:
30                 c[i][j] =c[i-1][j]
31                 flag[i][j] = ‘UP‘
32     printLcs(flag,str1,len1,len2)
33     return longest
34 a=‘ABCBDAB‘
35 b=‘BDCABA‘
36 print longSubSeq(a,b)
时间: 2024-10-06 01:10:35

最长公共子串和子序列的Python实现,带图示。的相关文章

最长公共子序列|最长公共子串|最长重复子串|最长不重复子串|最长回文子串|最长递增子序列|最大子数组和

参考:http://www.ahathinking.com/archives/124.html 最长公共子序列 1.动态规划解决过程 1)描述一个最长公共子序列 如果序列比较短,可以采用蛮力法枚举出X的所有子序列,然后检查是否是Y的子序列,并记录所发现的最长子序列.如果序列比较长,这种方法需要指数级时间,不切实际. LCS的最优子结构定理:设X={x1,x2,……,xm}和Y={y1,y2,……,yn}为两个序列,并设Z={z1.z2.……,zk}为X和Y的任意一个LCS,则: (1)如果xm=

最长递增子序列 &amp;&amp; 最大子序列、最长递增子序列、最长公共子串、最长公共子序列、字符串编辑距离

http://www.cppblog.com/mysileng/archive/2012/11/30/195841.html 最长递增子序列问题:在一列数中寻找一些数,这些数满足:任意两个数a[i]和a[j],若i<j,必有a[i]<a[j],这样最长的子序列称为最长递增子序列. 设dp[i]表示以i为结尾的最长递增子序列的长度,则状态转移方程为: dp[i] = max{dp[j]+1}, 1<=j<i,a[j]<a[i]. 这样简单的复杂度为O(n^2),其实还有更好的方

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

子串就是要连在一起的,而子序列就是满足这同时在1-n的母串中存在就好了. 比如abcdefg 子串有abc 子序列acdfg 动态规划 假设Z=<z1,z2,?,zk>是X与Y的LCS, 我们观察到 如果Xm=Yn,则Zk=Xm=Yn,有Zk?1是Xm?1与Yn?1的LCS: 如果Xm≠Yn,则Zk是Xm与Yn?1的LCS,或者是Xm?1与Yn的LCS. 因此,求解LCS的问题则变成递归求解的两个子问题.但是,上述的递归求解的办法中,重复的子问题多,效率低下.改进的办法--用空间换时间,用数组

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

最长公共子串与最长公共子序列是有区别的.区别在于最长公共子串要求字符是连续的. 例如:str1:  abcd      str2:  abec那么最长公共子序列是:abc,长度为3最长公共子串是:ab,长度为2 1. 最长公共子序列 Largest common subsequence 最长公共子序列:用f[i][j]表示str1的前i个字符与str2的前j个字符的最长公共子序列的长度. int LCS(int a[],int b[],int len) { vector<int> f(len+

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

最近工作中需要写一个算法,而写完这个算法我却发现了一个很有意思的事情.需要的这个算法是这样的:对于A,B两个字符串,找出最多K个公共子串,使得这K个子串长度和最大.一开始想了一些乱七八糟的想法. 错误想法1:比如每次找最长公共子串,找到一个子串后,从A,B两个字符串中删除这个子串,之后在剩下的串中再找最长公共子串,像这样找K次.但是可惜是错误的. 举个反例: A=KABCDELMABCDEFGNFGHIJK B=KABCDEFGHIJK K=2 按照这种方式选取结果为:ABCDEFG+HIJK,

[Data Structure] LCSs——最长公共子序列和最长公共子串

什么是 LCSs? 什么是 LCSs? 好多博友看到这几个字母可能比较困惑,因为这是我自己对两个常见问题的统称,它们分别为最长公共子序列问题(Longest-Common-Subsequence)和最长公共子串(Longest-Common-Substring)问题.这两个问题非常的相似,所以bbs.chinaacc.com/forum-2-3/topic-5611515.html bbs.chinaacc.com/forum-2-3/topic-5611514.html bbs.chinaac

动态规划算法之:最长公共子序列 & 最长公共子串(LCS)

1.先科普下最长公共子序列 & 最长公共子串的区别: 找两个字符串的最长公共子串,这个子串要求在原字符串中是连续的.而最长公共子序列则并不要求连续. 2.最长公共子串 其实这是一个序贯决策问题,可以用动态规划来求解.我们采用一个二维矩阵来记录中间的结果.这个二维矩阵怎么构造呢?直接举个例子吧:"bab"和"caba"(当然我们现在一眼就可以看出来最长公共子串是"ba"或"ab") b a b c 0 0 0 a 0 1

《算法导论》读书笔记之动态规划—最长公共子序列 &amp; 最长公共子串(LCS)

From:http://my.oschina.net/leejun2005/blog/117167 1.先科普下最长公共子序列 & 最长公共子串的区别: 找两个字符串的最长公共子串,这个子串要求在原字符串中是连续的.而最长公共子序列则并不要求连续. 2.最长公共子串 其实这是一个序贯决策问题,可以用动态规划来求解.我们采用一个二维矩阵来记录中间的结果.这个二维矩阵怎么构造呢?直接举个例子吧:"bab"和"caba"(当然我们现在一眼就可以看出来最长公共子串是

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

两道题都可以用动态规划的方法做,只是状态转移方程不同. 最长公共子串(注意子串是连续的) 1.先建立一个二维数组array[str1.size()][str2.size()](全部初始化为0),初始化第一行和第一列(元素相同处置1),然后进入状态方程 2.状态转移方程: if(str1[i] == str2[i]) array[i][j]=array[i-1][j-1]+1; (左上方对角线的值加上1) 否则无操作. 3.最后寻找整个array中的最大值即可(因为可能有多个子串) 1 /* 2