求两个字符串的最长公共子序列的长度(子序列不一定是原串中的连续子串组成)
LCS
LCS
使用动态规划
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int lcs_len(string s1, string s2)
{
int len1 = s1.size(), len2 = s2.size();
if (len1==0 || len2==0)
return 0;
//定义二维数组dp[i][j] 代表串1从0~i这段与串2从0~j这段的公共子串的最大值
//赋初值dp[0~len1][0]=0 dp[0][0~len2]=0
vector<vector<int> > dp(len1+1, vector<int>(len2+1,0));
for (int i = 1; i <=len1; i++)
{
for (int j = 1; j <=len2; j++)
{
if (s1[i - 1] == s2[j - 1])
{
//若相等则上层值+1
dp[i][j] = dp[i - 1][j - 1] + 1;
}
else{
//若不相等则等于交错值中的最大值
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
return dp[len1][len2];
}
//测试函数
int main()
{
string s1, s2;
while (cin >> s1 >> s2)
{
cout << lcs_len(s1, s2) << endl;
}
return 0;
}
测试样例:
最长公共子串
输入例子:
abcde
abgde
输出例子:
2
解题思路:
这题其实是动态规划的变形经典题型,应用动态规划的思想,创建一个二维数组dp[n][n],其中dp[i][j],表示取到s1[i]和取到s2[j]时的最大连续子串长度。如果s1[i]等于s2[j],则dp[i-1][j-1]等于取到s1[i-1]和取到s2[j-1]时的最大连续子串长度加1,即
dp[i][j]=dp[i-1][j-1]+1。
下面直接上代码:
#include <stdio.h>
#include <string.h>
#define N 50
int main(){
char s1[N],s2[N];
int dp[N][N],i,j,max_len=0;
gets(s1);
gets(s2);
for(i=0;i<strlen(s1);i++){
for(j=0;j<strlen(s2);j++){
if(s1[i]==s2[j]){
if(i>0&&j>0){
dp[i][j]=dp[i-1][j-1]+1;
}else{
dp[i][j]=1;
}
if(max_len<dp[i][j]){
max_len=dp[i][j];
}
}
}
}
printf("%d\n",max_len);
return 0;
}