1.dp矩阵
若s1[i]==s2[j],则dp[i][j]=dp[i-1][j-1]+1;
若s1[i]!=s2[j],则dp[i][j]=max{dp[i-1][j],dp[i][j-1]};
2.设定标记矩阵flag
若dp中元素从左上角得来,则flag中元素记为1;若从上边得来,则flag中元素记为2;若从左边得来,则flag中元素记为3;
3.lcs函数记录最长公共子序列
代码如下:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
string res;
void lcs(int i, int j, string s1,string s2,string &res, vector<vector<int> > flag)
{
if ((i== 0) && (j == 0))
{
if (flag[i][j] == 1)
res.push_back(s1[i]);
return;
}
if (flag[i][j] == 1)
{
res.push_back(s1[i]);
lcs(i - 1, j-1, s1, s2, res, flag);
}
else if (flag[i][j] == 2)
{
lcs(i-1,j,s1,s2,res,flag);
}
else
{
lcs(i,j-1,s1,s2,res,flag);
}
}
int main(int argc, char *argv[])
{
string s1, s2;
cin >> s1 >> s2;
int m = s1.size();
int n = s2.size();
vector<vector<int> > dp(m+1,vector<int>(n+1,0));
vector<vector<int> > flag(m,vector<int>(n,0));
for (int i = 0; i < n + 1; i++)
{
dp[0][i] = 0;
}
for (int i = 0; i < m + 1; i++)
{
dp[i][0] = 0;
}
for (int i = 1; i < m + 1; i++)
{
for (int j = 1; j < n + 1; j++)
{
if (s1[i-1] == s2[j-1])
{
dp[i][j] = dp[i - 1][j - 1] + 1;
flag[i - 1][j - 1] = 1;
}
else
{
if (dp[i - 1][j] > dp[i][j - 1])
{
dp[i][j] = dp[i-1][j];
flag[i - 1][j - 1] = 2;
}
else
{
dp[i][j] = dp[i][j-1];
flag[i - 1][j - 1] = 3;
}
}
}
}
lcs(m - 1, n - 1, s1, s2, res, flag);
for (int i = res.size() - 1; i >= 0; i--)
{
cout << res[i] << " ";
}
cout << endl;
return 0;
}