题目
给定两个字符串或数组序列A和B,求子序列为A和B之间的最长公共部分(子序列可以不连续)。
思路
如果直接用暴力的方法,适合字符串长度较小的情况,当字符串的长度很长,复杂度就会很大,那么可以用动态规划的办法解决。
- 设dp[i][j]表示字符串A的i号字符和B的j号字符之前的公共子序列长度;
- 根据A[i],B[j]的情况,可以分为两种情况;
- 如果A[i]==B[j],字符串A和字符串B的公共子序列的长度加1,即dp[i][j]=dp[i-1][j-1]+1;
- 如果A[i]!==B[j],那么字符串A的i号字符和B的j号字符之前的公共子序列无法延长,dp[i][j]会等于dp[i-1][j]和dp[i][j-1]中的较大值;
代码
#include<stdio.h>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=100;
char A[N],B[N];
int dp[N][N];
int main()
{
gets(A + 1);//从下标1开始读入
gets(B + 1);
int lenA = strlen(A + 1);
int lenB = strlen(B + 1);
for (int i = 0; i <= lenA; i++)
{
dp[i][0] = 0;
}
for (int j = 0; j<= lenB; j++)
{
dp[0][j] = 0;
}
for (int i = 1; i <= lenA; i++) //主要代码
{
for (int j = 1; j <= lenB; j++)
{
if (A[i] == B[j])
{
dp[i][j] = dp[i - 1][j - 1] + 1;
}
else {
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
printf("%d\n", dp[lenA][lenB]);
return 0;
}