题目描述
求两个字符串的最长公共子序列
输入:
两行,分别为待测的两组字符串。每个字符串长度不大于1000.。
输出:
第一行表示表示最长公共子序列长度。每组结果占一行。
第二行输出最长的公共子序列
输入样例1
asdf
adfsd
输出样例1
3
asd
输入样例2
123abc
abc123abc
输出样例2
6
123abc
思路
c[i][j] :表示序列{x1,x2,…xi}和序列{y1,y2…yj}最长公共子序列的长度
状态转移方程:
c[i][j] = 0 i > 0; j = 0
c[i][j] = c[i-1][j-1] + 1 i,j > 0; xi == yj
c[i][j] = max{c[i][j-1],c[i-1][j]} i,j > 0; xi != yj
代码
#include<iostream>
#include<cstring>
using namespace std;
const int N = 1e2 + 10;
char x[N];
char y[N];
int b[N][N];
int c[N][N];
void LCSLength()
{
int m = strlen(x);
int n = strlen(y);
for(int i = 0; i <= m; i++)
c[i][0]=0;
for(int j = 1; j <= n; j++)
c[0][j]=0;
for(int i = 1; i <= m; i++)
{
for(int j = 1; j <= n; j++)
{
if(x[i-1] == y[j-1])
{
c[i][j] = c[i-1][j-1]+1;
b[i][j] = 0;
}
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] = -1;
}
}
}
}
void PrintLCS(int i,int j)
{
if(i == 0 || j == 0)
return ;
if(b[i][j]==0)
{
PrintLCS(i - 1, j - 1);
printf("%c",x[i-1]);
}
else if(b[i][j] == 1)
PrintLCS(i - 1, j);
else
PrintLCS(i,j-1);
}
int main()
{
gets(x);gets(y);
LCSLength();
cout<<c[strlen(x)][strlen(y)]<<endl;
PrintLCS(strlen(x),strlen(y));
return 0;
}