DP方式求解:
#include <iostream>
using namespace std;
/**
* 问题描述:两个字符串,求解他们的最长公共子序列,子序列不要求连续
*
* 分析这个问题,我们可以发现有子结构,可以将X,Y两个字符串的最长公共子串
* 的问题转换成更小的子问题。而且这个问题的求解过程有重叠子问题。根据这两个
* 性质我们确定尝试用DP来解决。
* 首先定义状态,f(m,n),代表字符串X以Xm结尾的子串与字符串Y以Yn结尾的子串的
* 最长公共子序列。
* 如果Xm == Yn,那么问题转换成求解f(m-1,n-1),且f(m,n) = f(m-1,n-1)+1
* 如果Xm != Yn,那么最长公共子序列要么是X(m-1)结尾的子串与Yn结尾的子串的最长公共子序列
* 要么是Xm结尾的子串与Y(n-1)结尾的子串的最长公共子序列
* 根据上面分析很容易写出状态转移方程(递推式):
* f(m,n) =
* f(m,n) = f(m-1,n-1)+1. Xm == Yn
* f(m,n) = max{f(m,n-1),f(m-1,n)}. Xm != Yn
*
* 下面代码的任务就是自底向上求解这个状态转移方程。
*/
#define M 8 //行
#define N 7 //列
int dp[M][N] = {0};
int lcs_max(int x, int y){
return x>y?x:y;
}
/**
* DP求解最长公共子序列
*/
int lcs(const char *a, const char *b){
int row = M;
int col = N;
//初始化第一行和第一列
if(a[0] == b[0]) dp[0][0] = 1;
else dp[0][0] = 0;
for(int i=1;i<N;i++){
if(a[0] == b[i]) dp[0][i] = 1;
else dp[0][i] = 0;
}
for(int j=1;j<M;j++){
if(b[0] == a[j]) dp[j][0] = 1;
else dp[j][0] = 0;
}
//核心代码:自底向上求解DP矩阵(注意a是列,b是行)
for(i=1;i<row;i++){
for(j=1;j<col;j++){
if(a[i] == b[j]) dp[i][j] = dp[i-1][j-1]+1;
else dp[i][j] = lcs_max(dp[i-1][j], dp[i][j-1]);
}
}
//输出lcs矩阵
for(i=0;i<row;i++){
for(j=0;j<col;j++){
cout<<dp[i][j];
}
cout<<endl;
}
//返回最长子序列值
return dp[row-1][col-1];
}
int main(){
char *a = "aceddbcs"; //a作为DP矩阵的列(故DP矩阵8行)
char *b = "cebsdbc"; //b作为DP矩阵的行(故DP矩阵7列)
cout<<lcs(a,b)<<endl;
return 0;
}
分享到:
相关推荐
此问题的核心在于寻找两个序列的最长公共子序列。其中,“子序列”指的是在原序列中通过删除某些元素而得到的新序列,但删除过程中必须保持原序列中元素的相对顺序不变。 题目中给出的示例清晰地展示了什么是公共子...
首先,可以证明两个序列的最长公共子序列包含了这两个序列的前缀的最长公共子序列,因此,最长公共子序列问题具有最优子结构性质。然后,可以设计一个动态规划算法来解决该问题,具体来说,就是从第一个字符开始考虑...
如果它是源代码,我们可以期待找到一个或多个C++文件,里面包含使用MFC编写的函数或类,用于计算两个序列的最长公共子序列。如果它是测试数据,可能包含一些文本文件,每行代表一个序列,用于验证算法的正确性。 总...
最长公共子序列(Longest Common Subsequence,LCS)是一个经典的计算机科学问题,涉及序列比较和算法设计。在本实验报告中,我们将深入探讨如何利用动态规划方法解决这一问题。 首先,LCS问题旨在找到两个给定序列...
### C++实现最长公共子序列算法详解 在深入解析给定代码之前,我们先来了解一下“最长公共子序列”(Longest Common Subsequence,简称LCS)的基本概念及其在计算机科学中的应用。LCS问题是一种典型的动态规划问题...
C++ 语言写最长公共子序列问题是动态规划的经典问题之一,通过比较两个序列,找出它们之间的公共子序列,并输出该公共子序列的长度和内容。本问题有很多实际应用,并且在计算生物学等领域中有重要的研究价值。
最长公共子序列问题是指在给定的两个序列中找出最长的公共子序列。这里的子序列不要求在原序列中连续出现,但必须保持原序列中的相对顺序。例如,序列“ABCD”和“ACDF”的最长公共子序列是“ACD”。 **O(n^2)算法...
1. 最长公共子序列 一个给定序列的子序列是在该序列中删去若干元素后得到的序列。确切地说,若给定序列X=, x2,…, xm>,则另一序列Z=, z2,…, zk>是X的子序列是指存在一个严格递增的下标序列 , i2,…, ik>,使得...
利用动态规划 实现排序 找到最长公共工子序列
最长公共子序列问题(Longest Common Subsequence,LCS)是计算机科学中一个经典的问题,它是指给定两个序列X和Y,找出它们的最长公共子序列。该问题具有重要的理论和实际意义,在很多领域都有应用,如数据压缩、...
问题的核心是找到两个序列 X 和 Y 的最长公共子序列(LCS),即在删除若干元素后,X 和 Y 都能变成的子序列。例如,序列 {B,C,D,B} 是 {A,B,C,B,D,A,B} 的子序列,通过下标 {2,3,5,7} 显示这种关系。最长公共子序列...
在寻找最长公共子序列的问题中,最优子结构表现为:如果两个序列的最后一个字符相同,则最长公共子序列是除去这两个字符后的两个序列的最长公共子序列加上这个相同的字符;如果不同,就取两个序列去掉各自最后一个...
根据给定的文件信息,我们可以总结出以下关于“输出最长公共子序列”的C语言实现的知识点: ### 一、最长公共子序列问题介绍 最长公共子序列(Longest Common Subsequence,简称 LCS)是一个经典的计算机科学问题...
最长公共子序列(Longest Common Subsequence,简称LCS)是计算机科学中一种经典的问题,主要应用于比较和分析两个或多个序列的相似性。在这个问题中,目标是找到两个序列的最长子序列,这个子序列不需要在原序列中...
总结来说,最长公共子序列问题是一个典型的动态规划问题,通过使用C#编程语言,我们可以有效地求解两个字符串的最长公共子序列。这种算法在文本比较、生物信息学、软件工程等领域有广泛应用。理解并能实现这种算法...
最长公共子序列即为这两个序列的共同子序列中最长的那个。 例如,对于字符串`X = "ABCBDAB"`和`Y = "BDCAB"`,它们的一个公共子序列可以是`"BCAB"`,而最长公共子序列是`"BCAB"`,长度为4。 #### 动态规划算法在...
### 最长公共子序列动态规划算法 在计算机科学领域中,**最长公共子序列问题**(Longest Common Subsequence Problem, LCS)是一个经典的算法问题,它主要应用于文本比较、生物信息学中的DNA序列比对等领域。该问题...
最长公共子序列问题是指给定两个序列X和Y,求出这两个序列的最长公共子序列,也就是说,找出这两个序列中同时出现的最长子序列。例如,序列X:a,b,c,b,d,a,b,序列Y:b,d,c,a,b,a,則这两个序列的最长公共子序列为:...
动态规划的一个计算两个序列的最长公共子序列的方法如下: 以两个序列 X、Y 为例子: 设有二维数组 f[i,j] 表示 X 的 i 位和 Y 的 j 位之前的最长公共子序列的长度,则有: f[1][1] = same(1,1); f[i,j] = max{f[i-1...