题目
最长公共子序列
分析
有两个字符串S1和S2,求一个最长公共子串,即求字符串S3,它们同时是S1和S2的子串,且要求它们的长度最长,并确定这个长度。这个问题我们称之为最长公共子序列问题。
与求最长递增子序列一样,我们首先将原问题分割成一些子问题,我们用dp[i][j]表示S1中前i个字符和S2中前j个字符分别组成的两个前缀字符串的最长公共子串长度。显然的,当i,j较小时我们可以直接给出答案,如dp[0][j] 必等于0。那么,假设我们已经求的dp[i][j](0 <= i < x,0 <= j < y)的所有值,考虑如何在这些值继而推的dp[x][y],求的S1前x个字符组成的前缀子串和S2前y个字符组成的前缀子串的最长公共的子序列的长度。若S1[x] == S2[y],即S1中的第x个字符和S2中的第y个字符相同,同时由于他们都是各自前缀子串的最后一个字符,那么必存在一个最长的公共子串以S1[x]或S2[y]结尾。其他部分等价于S1中前x-1个字符和S2中前y-1个字符的最长公共子串。所以这个子串的长度比dp[x-1][y-1]增加1,即dp[x][y] = dp[x-1][y-1] + 1。相反的,若S1[x] != S2[y],此时其最长的公共子串长度为S1中前x-1个字符和S2中前y个字符的最长公共子串的长度与S1中前x个字符和S2中前y-1个字符的最长公共子串的长度的较大者,即在两种情况下得到的最长公共子串都不会因为其中一个字符串又增加了一个字符长度发生改变。综上所述,dp[x][y] = max{dp[x][y-1] , dp[x-1][y]}。
总结一下,最长公共子序列问题的递推条件:
假设有两个字符串S1和S2,其中S1长度为n,S2长度为m,用dp[i][j]表示S1前i个字符组成的前缀子串与S2前j个字符组成的前缀子串的最长公共子串长度,那么:
dp[0][j] = 0 (0 <= j <= m)
dp[i][0] = 0 (0 <= i <= n)
dp[i][j] = dp[i-1][j-1] + 1 (S1[i] == S2[j])
dp[i][j] = max{dp[i][j-1],dp[i-1][j]} (S1[i] != S2[j])
代码
#include <iostream>
#include <algorithm>
using namespace std;
class Solution {
public:
int LCS(string a,string b){
int sizea = a.size();
int sizeb = b.size();
if(sizea <= 0 || sizeb <= 0){
return 0;
}
int dp[sizea+1][sizeb+1];
for(int i = 0;i < sizea;++i){
for(int j = 0;j < sizeb;++j){
if(i == 0 || j == 0){
dp[i][j] = 0;
}
}
}
for(int i = 1;i <= sizea;++i){
for(int j = 1;j <= sizeb;++j){
if(a[i] == b[j]){
dp[i][j] = dp[i-1][j-1] + 1;
}
else{
dp[i][j] = max(dp[i][j-1],dp[i-1][j]);
}
}
}
return dp[sizea][sizeb];
}
};
int main() {
Solution solution;
string a("BDCABA");
string b("ABCBDAB");
cout<<solution.LCS(a,b)<<endl;
}
<script type="text/javascript">
$(function () {
$('pre.prettyprint code').each(function () {
var lines = $(this).text().split('\n').length;
var $numbering = $('<ul/>').addClass('pre-numbering').hide();
$(this).addClass('has-numbering').parent().append($numbering);
for (i = 1; i <= lines; i++) {
$numbering.append($('<li/>').text(i));
};
$numbering.fadeIn(1700);
});
});
</script>
分享到:
相关推荐
运用动态规划算法解决最长公共子序列问题,计算最长公共子序列长度的动态规划算法LCS_LENGTH(X,Y)以序列X=, x2, …, xm>和Y=, y2, …, yn>作为输入。输出两个数组c[0..m ,0..n]和b[1..m ,1..n]。其中c[i,j]存储Xi与...
最长公共子序列的两种算法简介,一种是平时最常见的算法,还有一种用滚动数组来做的。
算法系列之六:最长公共子序列(LCS)问题(连续子序列)的三种解法.doc
java算法分析与设计之最长公共子序列问题源代码 算法作为计算机专业学生的必修课,同时也是软件开发过程中必备的编程思想,对学习研究计算机专业意义重大;正因为这门课程难,所以除了相关方面的书籍,网络资源少的...
算法导论实验 最长公共子序列程序源码 实验报告
最长公共子序列.(C语言编写) 算法最长公共子序列.(C语言编写) 算法最长公共子序列.(C语言编写) 算法
本科算法实验-最长公共子序列【数据+代码+说明+流程图+测试用例】
实现了求最长公共子序列的算法,内容简单易懂,代码也很短
动态规划思维训练——最长公共子序列算法的设计与实现 给定两个序列X={X1, X2,···,Xm}和Y={Y1, Y2,···,Yn},找出X和Y的最长公共子序列(Longest Common Sequence)。 比如字符串X:{BDCABA};字符串Y:{...
动态规划解决最长公共子序列问题,即寻找两个序列中公共的序列中的最长的那个,结果不唯一,只能输出一个最长公共子序列,并不能生成所有的; 可视化多文档,手动输入两个子序列,显示动态规划算法的解决表格,箭头...
最长公共子序列问题,用C#实现的动态规划算法 X=ABCBDAB Y=BDCABA 以上是示例用的测试数据,输入数据可以得到结果
利用动态规划 实现排序 找到最长公共工子序列
这是一个有关算法的压缩包,里面包含二分算法、合并排序、最长公共子序列、最优装载、活动安排算法
动态规划的一个计算两个序列的最长公共子序列的方法如下: 以两个序列 X、Y 为例子: 设有二维数组 f[i,j] 表示 X 的 i 位和 Y 的 j 位之前的最长公共子序列的长度,则有: f[1][1] = same(1,1); f[i,j] = max{f[i-1...
C++求最长公共子序列!实用 花费了好长时间!!
最长公共子序列问题 最长公共子序列(动态规划) 实验数据:input.txt X={A,B,C,B,D,A,B}; Y={B,D,C,A,B,A} ——要求给出X、Y的最长公共子序列Z,程序运行结束时,将计算结果输出到文件output.txt中。输出文件中包含...
矩阵连乘、最长公共子序列 矩阵连乘、最长公共子序列
这是用动态规划算法求解给定的两个序列的最长公共子序列的C++程序。
求解任意两个字符串的最长公共子序列
算法导论实验:动态规划实现最长公共子序列问题,python实现; KR算法c语言实现。 附实验报告以及相关KMP算法的调研。