分析:
v[i][j]存储序列“a0,a1,…,ai-1”, “b0,b1,…,bj-1”的最长公共子序列的长度。
则v[i][j]的计算如下:
(1). v[i][j] = 0;
(2). v[i][j] = v[i-1][j-1]+1, 如果a[i-1] = b[j-1]
(3). v[i][j] = max(v[i-1][j],v[i][j-1]),如果a[i-1] != b[j-1]
C++代码:
解法一(递归法):
#include <iostream>
#include <vector>
#include <string>
using namespace std;
//在计算最优值,
int lcs_len(const string &s1,const string &s2, vector<vector<int>> &v, int i, int j)
{
if (i == 0 || j == 0)
{
v[i][j] = 0;
}
else
{
//不保证会求v中的每个元素
if (s1[i-1] == s2[j-1])
{
v[i][j] = lcs_len(s1,s2,v,i-1,j-1) + 1;
}
else
{
int L1 = lcs_len(s1,s2,v,i-1,j);
int L2 = lcs_len(s1,s2,v,i,j-1);
if (L1 >= L2)
{
v[i][j] = L1;
}
else
v[i][j] = L2;
}
}
return v[i][j];
}
//构造最长公共子序列,k为公共子序列长度
void buile_lcs(const string &s1,const string &s2,const vector<vector<int>> &v, int i, int j, string &sub/*, int k*/)
{
if (i == 0 || j == 0)
{
return ;
}
else
{
if (v[i][j] == v[i][j-1])
{
buile_lcs(s1,s2,v,i,j-1,sub);
}
else if (v[i][j] == v[i-1][j])
{
buile_lcs(s1,s2,v,i-1,j,sub);
}
else
{
sub = s1[i-1] + sub;
buile_lcs(s1,s2,v,i-1,j-1,sub);
}
}
}
int main()
{
string s1,s2;
cin>>s1>>s2;
int i = s1.length();
int j = s2.length();
vector<vector<int>> v;
vector<int> tmp(j+1,0);
for (int k=0;k<=i;++k)
{
v.push_back(tmp);
}
lcs_len(s1,s2,v,i,j);
string sub = "";
buile_lcs(s1,s2,v,i,j,sub);
/*for (vector<vector<int>>::iterator ita=v.begin();ita != v.end();++ita)
{
for (vector<int>::iterator itb=ita->begin();itb!= ita->end();++itb)
{
cout<<*itb<<' ';
}
cout<<endl;
}*/
cout<<sub<<endl;
return 0;
}
解法二:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
//在计算最优值
void lcs_len(const string &s1,const string &s2, vector<vector<int>> &v)
{
int len1 = s1.length();
int len2 = s2.length();
vector<int> tmp(len2+1,0);
// v.resize(len1+1);
for (int i=0;i<len1+1;++i)
{
v.push_back(tmp);
}
/*cout<<v.size()<<endl;*/
for (int i=1;i<len1+1;++i)
{
for (int j=1;j<len2+1;++j)
{
if (s1[i-1] == s2[j-1])
{
v[i][j] = 1+v[i-1][j-1];
}
else if (v[i-1][j] >= v[i][j-1])
{
v[i][j] = v[i-1][j];
}
else
{
v[i][j] = v[i][j-1];
}
}
}
}
//构造最长公共子序列,k为公共子序列长度
string buile_lcs(const string &s1,const string &s2,const vector<vector<int>> &v)
{
string com_subseq="";
int len1 = s1.length();
int len2 = s2.length();
int i = len1;
int j = len2;
int k = v[len1][len2];
while (k)
{
if (v[i][j] == v[i][j-1])
{
--j;
}
else if (v[i][j] == v[i-1][j])
{
--i;
}
else
{
com_subseq = s1[i-1]+com_subseq;
--i;
--j;
--k;
}
}
return com_subseq;
}
int main()
{
string s1,s2;
cin>>s1>>s2;
vector<vector<int>> v;
lcs_len(s1, s2,v);
/*for (vector<vector<int>>::iterator ita = v.begin();ita != v.end();++ita)
{
for (vector<int>::iterator itb = ita->begin();itb != ita->end();++itb)
{
cout<<*itb<<' ';
}
cout<<endl;
}
cout<<endl;*/
cout<<buile_lcs(s1,s2,v);
return 0;
}
运行结果:
输入:ABCBDAB BDCABA
输出:BDAB