本题来自poj1458,题目大意:给定两个字符串X,Y,求X,Y的最长公共子序列,不要求子序列连续,但子序列在X,Y中的位置是严格单调递增的。
例如 abcfbc与abfcab的最长公共子序列就是abcd,其长度为4;programming和contest的最长公共子序列就是on,其长度为2;abcd和mnp的最长公共子序列为空
可以采用动态规划的方法来解该题,计算字符串A、B的最长公共子序列
令L(i,j)表示A中前i个字符和B中前j个字符的最长公共子序列
则L(i+1,j+1)等于多少?
1.当A[i+1]=B[j+1]时,L(i+1,j+1) = L(i,j)+1
2.如果A[i+1] != B[j+1],则L(i+1,j+1) = max(L(i+1,j), L(i,j+1))
在上边界和右边界上的值为零
#include <stdio.h>
#include <string.h>
int L[1000][1000];
/*计算字符串A、B的最长公共子序列,采用动态规划的解法
L(i,j)表示A中前i个字符和B中前j个字符的最长公共子序列
则L(i+1,j+1)等于多少?
1.当A[i+1]=B[j+1]时,L(i+1,j+1) = L(i,j)+1
2.如果A[i+1] != B[j+1],则L(i+1,j+1) = max(L(i+1,j), L(i,j+1))
*/
int TheCommonSubsequence(char *strA, int lengthA, char *strB, int lengthB)
{
int i, j;
for (i = 0; i < lengthA; i++)
{
L[0][i] = 0;
L[i][0] = 0;
}
for (i = 1; i < lengthA; i++)
{
for (j = 1; j < lengthB; j++)
{
if (strA[i] == strB[j])
L[i][j] = L[i - 1][j - 1] + 1;
else
{
L[i][j] = (L[i - 1][j] > L[i][j - 1]) ? L[i - 1][j] : L[i][j - 1];
}
}
}
return L[lengthA - 1][lengthB - 1];
}
int main()
{
char strA[1000], strB[1000];
while (EOF != scanf("%s %s", strA + 1, strB + 1))
{
printf("%d\n", TheCommonSubsequence(strA, strlen(strA), strB, strlen(strB)));
}
return 0;
}