求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);
}

比如输入结果:
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(把顺序反过来即可)