算法设计–公共子序列问题
输入两个序列(以定义数组赋初值给定值),输出如教材P68页所示的优化函数表表3.7和标记函数表表3.8(提示:↖↑←三个符号可用数值1,0,-1代替处理,只有输出时才输出这个符号),及最长公共子序列。测试数据为:
序列组:X:<A,B,C,B,D,A,B> Y:<B,D,C,A,B,A>
递推方程
核心代码
void LCS(char x[],char y[],int m,int n){
int i,j;
for(i=1;i<=m;i++){
for(j=1;j<=n;j++){
if(x[i]==y[j]){
c[i][j]=c[i-1][j-1]+1;//将最大公共序列长度加一
b[i][j]=1;//标记公共子序列元素 ,被选入
}
else if(c[i-1][j]>c[i][j-1]){
c[i][j]=c[i-1][j];//最长公共子序列为Xi-1与Yj的最长公共子序列
b[i][j]=0; //向上不考虑Xi
}
else{
c[i][j]=c[i][j-1];//最长公共子序列为Xi与Yj-1的最长公共子序列
b[i][j]=-1; //向左不考虑Yi
}
}
}
}
完整代码
#include <iostream.h>
#include <iomanip.h>
#define M 20
int c[M][M]={0};
int b[M][M]={0};//初始化全局数组即优化函数与标记函数
char m[M]="\0ABCBDAB";
char n[M]="\0BDCABA";
void Display(int g[][M],char h,int m,int n){
int i,j; //两层循环通用输出标记函数与优化函数
for(i=0;i<=m;i++){
for(j=0;j<=n;j++){
cout<<setw(3)<<h<<"["<<i<<"]"<<"["<<j<<"]"<<" "<<"="<<setw(3)<<g[i][j];
}
cout<<endl;
}
}
void Display2(int g[][M],int m,int n){
int i,j; //适用于标记函数(箭头指示)输出
for(i=1;i<=m;i++){
cout<<i<<setw(4);
for(j=1;j<=n;j++){
cout<<"B["<<i<<","<<j<<"]=";
if(b[i][j]==1)
cout<<"↖ ";//当标记函数为1时,追溯方向为↖
if(b[i][j]==0)
cout<<"↑ ";//当标记函数为0时,追溯方向为↑
if(b[i][j]==-1)
cout<<"← "; //当标记函数为-1时,追溯方向为←
}
cout<<endl;
}
}
void LCS(char x[],char y[],int m,int n){
int i,j;
for(i=1;i<=m;i++){
for(j=1;j<=n;j++){
if(x[i]==y[j]){
c[i][j]=c[i-1][j-1]+1;//将最大公共序列长度加一
b[i][j]=1;//标记公共子序列元素 ,被选入
}
else if(c[i-1][j]>=c[i][j-1]){
c[i][j]=c[i-1][j];//最长公共子序列为Xi-1与Yj的最长公共子序列
b[i][j]=0; //向上不考虑Xi
}
else{
c[i][j]=c[i][j-1];//最长公共子序列为Xi与Yj-1的最长公共子序列
b[i][j]=-1; //向左不考虑Yi
}
}
}
}
int t;//全局变量t
void Maxreturn(int s[M][M],int m,int n){
t=s[m][n];//将最大公共子序列长度赋给t
}
void structureSequence(int s[M][M],char x[],int m,int n){
if(m==0||n==0)
return;
if(s[m][n]==1){
structureSequence(s,x,m-1,n-1);//当标记函数为1时向左上角追溯标记函数
cout<<x[m]; //先递归后输出,正序
if(--t)
cout<<",";//由t决定逗号个数 (输出格式美化)
}
else if(s[m][n]==0){
structureSequence(s,x,m-1,n);//当标记函数为0时向上追溯标记函数
}
else structureSequence(s,x,m,n-1);//当标记函数为-1时向左追溯标记函数
}
int main(){
LCS(m,n,7,6);
cout<<"实例一优化函数C[i][j]"<<endl;
Display(c,'C',7,6);
cout<<"====================================================================================================="<<endl;
cout<<"实例一标记函数B[i][j]"<<endl;
Display(b,'B',7,6);
cout<<"标记函数(箭头版):" <<endl;
Display2(b,7,6);
cout<<"====================================================================================================="<<endl;
Maxreturn(c,7,6);
cout<<"X与Y的最长公共子序列为:<";
structureSequence(b,m,7,6);
cout<<">"<<endl;
}
运行结果
结语
制作不易,点赞加关注,谢谢支持!
有任何代码上的问题可以私信交流。