输入两个序列(以定义数组赋初值给定值),输出如教材P68页所示的优化函数表表3.7和标记函数表表3.8(提示:↑↖←三个符号可用数值1,0,-1代替处理,只有输出时才输出这个符号),及最长公共子序列。测试数据为:
1组:X:<A,B,C,B,D,A,B> Y:<B,D,C,A,B,A>
2组:X:<1,3,4,5,6,7,7,8> Y:<3,5,7,4,8,6,7,8,2>
#include <iostream>
#include <stdio.h>
using namespace std;
char x[100]={0,'A','B','C','B','D','A','B'},y[100]={0,'B','D','C','A','B','A'};//两个序列
//char x[100]={0,'1','3','4','5','6','7','7','8'},y[100]={0,'3','5','7','4','8','6','7','8','2'};//第二组测试数据
int c[100][100]={0},z[100];//c[i][j]表示xi,yi的最长公共子序列,z[100]记录X和Y相同序列在X的位置
char b[100][100];//b[i][j]是标记函数,1代表"↑",2代表"←",3代表"↖"
void recall(int i,int j)//应用递归算法输出解的追踪过程
{
if(j==0) cout<<"j=0"<<endl<<endl;//当j为0时,Y序列为空输出标识j=0
else if(i==0) cout<<"i=0"<<endl<<endl;//当i为0时,X序列为空输出标识i=0
else
{
printf("B[%d,%d]→",i,j);//输出追踪过程
if(b[i][j]=='3') recall(i-1,j-1);//3代表"↖" ,斜向上走
if(b[i][j]=='2') recall(i,j-1);//2代表"←",向左走
if(b[i][j]=='1') recall(i-1,j);//1代表"↑",向上走
}
}
void refind(int i,int j,int k)//应用递归算法得出解
{
if(j==0||i==0)//X或Y序列为空结束
{
cout<<"”↖“"<<endl<<endl;//输出标识”↖“
return;//结束
}
if(b[i][j]=='3')//3代表"↖" ,斜向上走
{
z[++k]=i;//z[++k]记录X和Y相同序列在X的位置
printf("B[%d,%d]=",i,j);//输出b[i][j]为↖的情况
refind(i-1,j-1,k);
}
if(b[i][j]=='2') refind(i,j-1,k);//2代表"←",向左走
if(b[i][j]=='1') refind(i-1,j,k);//1代表"↑",向上走
}
void findArray(int m,int n)//动态规划寻找最长公共子序列
{
for(int i=1;i<=m;i++)//前面c[100][100]={0}的操作已使c[0][j]和c[i][0]=0了
for(int j=1;j<=n;j++)
if(x[i]==y[j])
{
c[i][j]=c[i-1][j-1]+1;//c[i][j]存储最大子序列长度
b[i][j]='3';//标记函数b[i][j]='↖'
}
else if(c[i-1][j]>=c[i][j-1])//max{c[i-1][j],c[i][j-1]}
{
c[i][j]=c[i-1][j];//c[i][j]存储最大子序列长度
b[i][j]='1';//b[i][j]='↑'
}
else
{
c[i][j]=c[i][j-1];//c[i][j]存储最大子序列长度
b[i][j]='2';//标记函数b[i][j]='←'
}
cout<<"优化函数c[i,j]如下:"<<endl;
for(int i=0;i<=m;i++)//输出优化函数
{
for(int j=1;j<=n;j++)
printf("c[%2d,%2d]=%2d ",i,j,c[i][j]);
cout<<endl;
}
cout<<"标记函数b[i,j]如下:"<<endl;
for(int i=1;i<=m;i++)//输出标记函数
{
for(int j=1;j<=n;j++)
{
printf("b[%2d,%2d]=",i,j);//输出
if(b[i][j]=='1') printf("↑ ");//3代表"↖" ,斜向上走
if(b[i][j]=='2') printf("← ");//2代表"←",向左走
if(b[i][j]=='3') printf("↖ ");//1代表"↑",向上走
}
cout<<endl;
}
cout<<"解的追踪过程为:"<<endl;//输出解释
recall(m,n);//应用递归算法输出解的追踪过程
cout<<"其中";
refind(m,n,0);//应用递归算法得出解
cout<<"这就得出解z=<";
for(int k=c[m][n];k>=1;k--)//输出相同的子序列在x的位置
{
if(k==1) cout<<'x'<<z[k]<<">=<";//最后一个数据输出
else cout<<'x'<<z[k]<<',';//逗号隔开
}
for(int k=c[m][n];k>=1;k--)//输出相同的子序列
{
if(k==1) cout<<x[k]<<'>'<<endl<<endl;//最后一个输出
else cout<<x[k]<<',';//逗号隔开
}
}
int main()
{
int m=7,n=6;//序列x和y的长度
//int m=8,n=9;//第二组测试数据
findArray(m,n);//动态规划寻找最长公共子序列
}
运行结果