3-4 最长公共子序列
一、题目

二、分析





三、代码
//最长公共子序列
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int c[100][100];//c[i][j]记录最长公共子序列的长度
int s[100][100];//为了构造最优解使用的
string x,y;
void Print(int a[100][100],int m,int n){
cout<<"---------------------\n";
for(int i=0;i<=m;i++){
for(int j=0;j<=n;j++){
cout<<a[i][j]<<" ";
}
cout<<endl;
}
cout<<"-------------------------\n";
}
void LCSLength(int m,int n){
for(int i=1;i<=m;i++) c[i][0]=0;//初始化
for(int j=1;j<=n;j++) c[0][j]=0;//初始化 i==0||j==0表示一个序列为空,故c[i][j]=0;
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(x[i]==y[j]){
c[i][j]=c[i-1][j-1]+1;
s[i][j]=1;
}
else{
if(c[i-1][j]>=c[i][j-1]){
c[i][j]=c[i-1][j];
s[i][j]=2;
}
else{
c[i][j]=c[i][j-1];
s[i][j]=3;
}
}
}
}
}
void LCS(int i,int j){ //用了辅助数组s[i][j]
if(i==0||j==0) return;
if(s[i][j]==1){
LCS(i-1,j-1);
cout<<x[i];
}
else if(s[i][j]==2)
LCS(i-1,j);
else if(s[i][j]==3)
LCS(i,j-1);
}
void LCS2(int i,int j){ //不用辅助数组s[i][j]
if(i==0||j==0) return;
if(x[i]==y[j]){
LCS(i-1,j-1);
cout<<x[i];
}
else if(c[i-1][j]>=c[i][j-1])
LCS(i-1,j);
else if(c[i-1][j]<c[i][j-1])
LCS(i,j-1);
}
void LCS3(int i,int j){ //不用辅助数组s[i][j]
if(i==0||j==0) return;
if(c[i][j]==c[i-1][j-1]+1){
LCS(i-1,j-1);
cout<<x[i];
}
else if(c[i][j]==c[i-1][j])
LCS(i-1,j);
else if(c[i][j]==c[i][j-1])
LCS(i,j-1);
}
int main(){
int m,n;
// cin>>x>>y;
x="abc";
y="ac";
m=x.length();
n=y.length();
cout<<"m="<<m<<" n="<<n<<endl;
x=' '+x;
y=' '+y;
LCSLength(m,n);//求解最优值
cout<<"LCS=";
LCS(m,n); //构造最优解
cout<<"\nLCS2=";
LCS2(m,n);//法2 构造最优解
cout<<"\nLCS3=";
LCS3(m,n);//法2 构造最优解
cout<<"\ncij\n";
Print(c,m,n);
cout<<"sij\n";
Print(s,m,n);
return 0;
}
四、运行结果

本文详细介绍了如何使用动态规划解决最长公共子序列问题,并提供了三种不同的实现方法及其代码示例,帮助读者深入理解该算法的工作原理。
825

被折叠的 条评论
为什么被折叠?



