求2个字符串的最长公共子序列(Longest Common Subsequence)
运用动态规划,复杂度为O(mn)m,n分别为两子序列长度
设:
两个序列Xi 和Yj的lcs为c[i,j]
如果图片显示不清楚,可在:
http://super-jiju.spaces.live.com/blog/cns!806C498DDEE76B61!270.entry
查看
根据上面的递归式即可
但不需要用递归求解,因为c[i,j]已经保存了每一对值
然后,回溯求得
#include
<
iostream
>
#include < string >
using namespace std;
int lcs( string A, string B);
int c[ 100 ][ 100 ] = {0} ;
int b[ 100 ][ 100 ] = {0} ;
void image( int i, int j, string & A);
int main()
{
string a,b;
cin>>a>>b;
if(a.length()>100 || b.length()>100)
{
cerr<<"Can not get the lcs of the string which length over 100"<<endl;
exit(0);
}
string &aa=a;
cout<<" "<<endl;
lcs(a,b);
cout<<" "<<endl;
image(a.length(),b.length(),aa);
cout<<endl;
system("pause");
return 0;
}
int lcs( string A, string B)
{
int mA=A.length();
int nB=B.length();
int len=0;
for(int i=1;i<=mA;++i)
{
for(int j=1;j<=nB;++j)
{
if(A.at(i-1)==B.at(j-1))
{
c[i][j]=c[i-1][j-1]+1;
len++;
b[i][j]=3;
}
else if(c[i-1][j]>=c[i][j-1])
{
c[i][j]=c[i-1][j];
b[i][j]=1;
}
else
{
c[i][j]=c[i][j-1];
b[i][j]=2;
}
}
}
//-----image the road
for(int j=1;j<=nB;++j)
{
cout<<" "<<B.at(j-1);
}
cout<<endl;
for(int i=1;i<=mA;++i)
{
cout<<A.at(i-1)<<" ";
for(int j=1;j<=nB;++j)
{
cout<<b[i][j]<<" ";
}
cout<<" "<<endl;
}
return len;
}
void image( int i, int j, string & A)
{
//-----3:up and left,1:up,2:left
if(i==0||j==0)
return;
if (b[i][j]==3)
{
cout<<A.at(i-1)<<" ";
image(i-1,j-1,A);
}
if(b[i][j]==1)
image(i-1,j,A);
if(b[i][j]==2)
image(i,j-1,A);
}
#include < string >
using namespace std;
int lcs( string A, string B);
int c[ 100 ][ 100 ] = {0} ;
int b[ 100 ][ 100 ] = {0} ;
void image( int i, int j, string & A);
int main()
{
string a,b;
cin>>a>>b;
if(a.length()>100 || b.length()>100)
{
cerr<<"Can not get the lcs of the string which length over 100"<<endl;
exit(0);
}
string &aa=a;
cout<<" "<<endl;
lcs(a,b);
cout<<" "<<endl;
image(a.length(),b.length(),aa);
cout<<endl;
system("pause");
return 0;
}
int lcs( string A, string B)
{
int mA=A.length();
int nB=B.length();
int len=0;
for(int i=1;i<=mA;++i)
{
for(int j=1;j<=nB;++j)
{
if(A.at(i-1)==B.at(j-1))
{
c[i][j]=c[i-1][j-1]+1;
len++;
b[i][j]=3;
}
else if(c[i-1][j]>=c[i][j-1])
{
c[i][j]=c[i-1][j];
b[i][j]=1;
}
else
{
c[i][j]=c[i][j-1];
b[i][j]=2;
}
}
}
//-----image the road
for(int j=1;j<=nB;++j)
{
cout<<" "<<B.at(j-1);
}
cout<<endl;
for(int i=1;i<=mA;++i)
{
cout<<A.at(i-1)<<" ";
for(int j=1;j<=nB;++j)
{
cout<<b[i][j]<<" ";
}
cout<<" "<<endl;
}
return len;
}
void image( int i, int j, string & A)
{
//-----3:up and left,1:up,2:left
if(i==0||j==0)
return;
if (b[i][j]==3)
{
cout<<A.at(i-1)<<" ";
image(i-1,j-1,A);
}
if(b[i][j]==1)
image(i-1,j,A);
if(b[i][j]==2)
image(i,j-1,A);
}
ABCBDAB
BDCABA
得到:
B D C A B A
A 1 1 1 3 2 3
B 3 2 2 1 3 2
C 1 1 3 2 1 1
B 3 1 1 1 3 2
D 1 3 1 1 1 1
A 1 1 1 3 1 3
B 3 1 1 1 3 1
A B C B(把顺序反过来即可)