/*
函数:最长公共子序列 (LCS,longest common subsequence problem) 动态规划解决该问题.
算法见 算法导论 原书第三版 殷建平 P224
一个给定的子序列就是将给定的一个或多个元素去掉之后的结果.
最长公共子序列,求x,y长度最长的公共子序列.
x={x1,x2...xm} y={y1,y2...yn}
分情况:
1.当xm=yn时,应该求解x(m-1)和y(n-1)的LCS,然后将xm或者yn加到LCS的队尾
2.当xm!=yn时,应求解两个子问题
求x(m-1)和y的LCS和x与y(n-1)的一个LCS
比较两个LCS的长度,取较长者.
覆盖了所有的可能性.
含有共享子问题
时间:15.7.24
Jason Zhou
热爱你所写下的程序,他是你的伙伴,而不是工具.
*/
#include<iostream>
using namespace std;
int print_arr(char x[],int len)
{
//int len=sizeof(x)/sizeof(x[0]);
cout<<"-----------------------len="<<len<<endl;
for (int i=0;i<len;i++)
{
cout<<" "<<x[i];
}
cout<<endl;
return 0;
}
int ** new_arr(int m,int n)
{
int **b=new int *[m];
for (int i=0;i<m;i++)
{
b[i]=new int[n];
}
return b;
}
int delete_arr(int **b,int m)
{
for (int di=0;di<m;di++)
{
delete [] b[di];
}
delete b;
return 0;
}
int print_lcs(int **b,char x[],char y[],int lx,int ly)
{
if (lx==-1 || ly==-1)
{
return 0;
}
if (1==b[lx-1][ly-1])
{
print_lcs(b,x,y,lx-1,ly-1);
cout<<" "<<x[lx-1];
}
else if (2==b[lx-1][ly-1])
{
print_lcs(b,x,y,lx-1,ly);
}
else
{
print_lcs(b,x,y,lx,ly-1);
}
return 0;
}
int lcs_length(char x[],int lenx,char y[],int leny)
{
int m=lenx;
int n=leny;
int **b=new_arr(m,n);
int **c=new_arr(m+1,n+1);
for (int i=0;i<m+1;i++)
{
c[i][0]=0;
}
for (int j=1;j<n+1;j++)
{
c[0][j]=0;
}
for (int i=1;i<m+1;i++)
for(int j=1;j<n+1;j++)
{
if (x[i-1]==y[j-1])
{
c[i][j]=c[i-1][j-1]+1;
b[i-1][j-1]=1;//代表指向左上
}
else if(c[i-1][j]>=c[i][j-1])
{
c[i][j]=c[i-1][j];
b[i-1][j-1]=2;//代表指向上
}
else
{
c[i][j]=c[i][j-1];
b[i-1][j-1]=3;//代表指向左
}
}
cout<<"#c---------------------"<<endl;
for (int i=0;i<m+1;i++)
{
for(int j=0;j<n+1;j++)
{
cout<<" "<<c[i][j];
}
cout<<endl;
}
cout<<"#b---------------------"<<endl;
for (int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
cout<<" "<<b[i][j];
}
cout<<endl;
}
cout<<"最长公共子序列-------------"<<endl;
print_lcs(b,x,y,m,n);
delete_arr(b,m);
delete_arr(c,m+1);
cout<<endl;
return 0;
}
int main()
{
char x[]={'a','b','c','b','d','a','b'};
char y[]={'b','d','c','a','b','a'};
int len1=sizeof(x)/sizeof(x[0]);
print_arr(x,len1);
int len2=sizeof(y)/sizeof(y[0]);
print_arr(y,len2);
lcs_length(x,len1,y,len2);
return 0;
}
最长公共子序列 (LCS,longest common subsequence problem) 动态规划
最新推荐文章于 2022-10-04 15:54:41 发布