输入:
X={x1,x2,……,xm}
Y={y1,y2,……,ym}
输出:
Z=X和Y的最长公共子序列
说明:
如果: X={A,B,C},Y={A,C,D} ,则X和Y的最长公共子序列 Z={A,C}
我们将一个序列如 X 的前 i 个元素定义: Xi ,则有 Xi={x1,x2,……,xi}
我们将 XY 的最长公共子序列记为 LCSXY
我们将 X 的前 i 个和 Y 的前 j 个元素的最长公共子序列记为 LCSXiYj
我们假设 LCSXmYn=Z={z1,……,zk}
我们就可以知道 LCSXm−1Yn−1 和 LCSXmYn 之间的关系为:
(1)当 Xm=Yn 时:
(2)当 Xm≠Yn⋀zk≠xm 时:
(3)当 Xm≠Yn⋀zk≠yn 时:
我们定 c[i][j] 等于 LCSXiYj 里面元素的个数
我们有以下的递推方程:
(1)当 i=0⋁j=0 时:
(2)当 i>0⋀j>0⋀xi=yj 时:
(2)当 i>0⋀j>0⋀xi≠yj 时:
我们现在有一个二维表,抽取其中的 c[i−1][j−1],c[i−1][j],c[i][j−1],c[i][j] 来进行分析,如下图
我们在知道 c[i][j] 的旁边的 c[i−1][j−1],c[i−1][j],c[i][j−1] 这三个数的值之后就可以得到 c[i][j] 的值!
我们取一个 X 和 Y 里面元素个数都是4的实例进行分析:
画出如图的二维表,我们目的是求出最右下角的 c[4][4] :
接下来我们就可以由以上已知的部分依次得到最长公共序列的个数!
比如: c[1][1] 可以根据左上半部 c[0][0],c[0][1],c[1][0] 得到!
现在我们根据上面的方法可以得到相应最长公共子序列的个数了,那么怎样得到这个最长公共子序列呢?
我们只需要从这个二维表的最右下角向左上角回溯即可!详细看代码:
int num=0;
int i=xLen;
int j=yLen;
//回溯获得最长子序列
while(i!=0&&j!=0){
if(c[i][j]!=c[i-1][j]){
z[++num]=x[i];
j--;
i--;
while(c[i][j]==c[i][j-1]) j--;
}else{
i--;
}
}
如果觉得上面说的太过于啰嗦,或者我表述的并不是很清晰,那么我们就直接看代码吧!
#include
#include
#define MAX_LEN 100
using namespace std;
/**
* @author zjq~
* @time 2017/07/08
* @func 动态规划求解最长公共子序列问题
*/
char x[MAX_LEN]; //两个子序列
char y[MAX_LEN];
int xLen=0; //两个子序列的长度
int yLen=0;
char z[MAX_LEN]; //保存最长公共子序列
int c[MAX_LEN][MAX_LEN]; //记录LCS[i][j] 的个数
void getLCS() {
//构造二维表
for(int i=0; i<=xLen; i++) {
for(int j=0; j<=yLen; j++) {
if(i==0||j==0) {
c[i][j]=0;
} else if(i>0&&&j>0&&x[i]==y[j]) {
c[i][j]=c[i-1][j-1]+1;
} else {
c[i][j]=c[i-1][j]>c[i][j-1]?c[i-1][j]:c[i][j-1];
}
}
}
int num=0;
int i=xLen;
int j=yLen;
//回溯获得最长子序列
while(i!=0&&j!=0){
if(c[i][j]!=c[i-1][j]){
z[++num]=x[i];
j--;
i--;
while(c[i][j]==c[i][j-1]) j--;
}else{
i--;
}
}
}
int main() {
cin>>xLen; //下标从 i=1 开始
for(int i=1; i<=xLen; i++) {
cin>>x[i];
}
cin>>yLen;
for(int i=1; i<=yLen; i++) {
cin>>y[i];
}
getLCS(); //获得最长公共子序列
cout<<"最长公共子序列包含元素个数为:"<cout<<"最长公共子序列为:";
for(int i=c[xLen][yLen];i>0;i--){
cout<" ";
}
cout<
运行结果截图:
去九度OJ提交一下看看你的代码是否正确吧!
http://ac.jobdu.com/problem.php?pid=1042
注意一下两点:
使用gets
加上头文件#include
OJ上面的题目需要测试多组数据,注意使用while(gets(x)){}