先求两字符串的最长公共子序列,并记录公共子序列每个字符在两字符串中的位置。然后,按要求输出结果。详见代码。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 111;
char s1[maxn], s2[maxn], ans[maxn*2];
int len[maxn][maxn];
int pre[maxn][maxn];
int id1[maxn], id2[maxn]; // 公共子序列每个字符在字符串s1和s2中的下标
int cnt;
int DP()
{
memset(len, 0, sizeof(len));
int l1 = strlen(s1);
int l2 = strlen(s2);
for (int i = 1; i <= l1; ++i)
{
for (int j = 1; j <= l2; ++j)
{
if (s1[i-1] == s2[j-1])
{
len[i][j] = len[i-1][j-1] + 1;
pre[i][j] = 0;
}
else if (len[i-1][j] > len[i][j-1])
{
len[i][j] = len[i-1][j];
pre[i][j] = 1;
}
else
{
len[i][j] = len[i][j-1];
pre[i][j] = 2;
}
}
}
return len[l1][l2];
}
void getIndex(int i, int j)
{
if (i == 0 || j == 0)
return ;
if (pre[i][j] == 0)
{
getIndex(i - 1, j - 1);
id1[cnt] = i - 1; id2[cnt] = j - 1;
cnt++;
}
else if (pre[i][j] == 1)
getIndex(i - 1, j);
else getIndex(i, j - 1);
}
int main()
{
while (scanf("%s %s", s1, s2) != EOF)
{
int LEN = DP();
cnt = 0;
getIndex(strlen(s1), strlen(s2));
int idx = 0, i = 0, j = 0, k = 0;
for ( ; i < LEN; ++i)
{
for ( ; j < id1[i]; ++j)
ans[idx++] = s1[j];
for ( ; k < id2[i]; ++k)
ans[idx++] = s2[k];
ans[idx++] = s1[j];
j++; k++;
}
while (s1[j] != '\0')
ans[idx++] = s1[j++];
while (s2[k] != '\0')
ans[idx++] = s2[k++];
ans[idx] = '\0';
printf("%s\n", ans);
}
return 0;
}