求两个字符串的最长公共子序列的长度(子序列不一定是原串中的连续子串组成)
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; }