#include <stdio.h>
#include <algorithm>
#include <string.h>using namespace std;
char str1[101];
char str2[101];
int dp[101][101];
char tmp[101];int main()
{
//这里输入的时候将str1和str2都加一,是为了方便后面dp的计算
while(~scanf("%s%s", str1+1, str2+1))
{
int len1 = strlen(str1+1);
int len2 = strlen(str2+1);
for(int i = 0; i <= len1; i++)
dp[i][0] = 0;
for(int j = 0; j <= len2; j++)
dp[0][j] = 0;
for(int i = 1; i <= len1; i++)
for(int j = 1; j <= len2; j++)
{
if(str1[i] == str2[j])
dp[i][j] = dp[i-1][j-1] + 1;
else
dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
}
if(dp[len1][len2] == 0)
{
printf("%s%s\n", str1+1, str2+1);
continue;
}
//这部分不太懂
int k = 0;
for(int i = len1, j = len2; i > 0, j > 0;)
{
if(dp[i][j] == dp[i-1][j-1] + 1 && str1[i] == str2[j])
{
tmp[k++] = str1[i];
i--;
j--;
}
else if(dp[i-1][j] > dp[i][j-1])
i--;
else
j--;
}
/*
最外层for循环开始计数,先输出最长公共子串tmp[k]之前的str1和str2的字符,再输出tmp[k],
最后再输出未匹配得到的剩余字符,这样可保证名字最短,而且名字的子串中肯定有str1和str2
*/
int p = 1, q = 1;
for(int i = k-1; i >= 0; i--)
{
while(p < len1 && str1[p] != tmp[i])
{
printf("%c", str1[p]);
p++;
}
while(q < len2 && str2[q] != tmp[i])
{
printf("%c", str2[q]);
q++;
}
printf("%c", tmp[i]);
//输出公共字符后要将p和q加一
p++;
q++;
}
printf("%s%s\n", str1+p, str2+q);
}
return 0;
}
HDU-1503-Advanced fruits(最长公共子序列)
最新推荐文章于 2020-05-28 14:18:17 发布