来源:labuladong的算法小抄
题目:最长公共子序列(Longest Common Subsequence),求两个字符串的LCS长度。
例:str1: abcde
str2: aceb
结果:3 (最长子序列为ace)
第一步:明确dp数组的含义
dp[i][j]:对str1[0...i-1]和str2[0...j-1]的LCS长度。
第二步:定义base case
索引为0的行和列来表示空串,dp[0][...]和dp[...][0]初始化为0.
0 | 1 | 2 | 3 | 4 | 5 | 6 | ||
srt1\str2 | ... | b | a | b | c | d | e | |
0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | a | 0 | ||||||
2 | c | 0 | ||||||
3 | e | 0 |
第三步:找状态转换方程
dp [i][j] = {
dp[i-1][j-1]+1; str1[i] ==str2[j]
max{dp[i-1,j],dp[i,j-1] }; str1[i] != str2[j]
}
代码如下:
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
int LongestCommonSubquence(char str1[],char str2[])
{
int m = strlen(str1);
int n = strlen(str2);
cout<<str1<<endl;
cout<<"m="<<m<<endl;
cout<<str2<<endl;
cout<<"n="<<n<<endl;
//把dp[0][...]和dp[...][0]都初始化为0 输出dp数组可以知道已经全部初始化为0
vector<vector<int>> dp(m+1,vector<int>(n+1,0));
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
if(int(str1[i-1]) == int(str2[j-1]))
{
dp[i][j] = (dp[i-1][j-1]+1);//又把= 写成了“==” !!!
}
else{
if(dp[i-1][j] > dp[i][j-1])
{
dp[i][j]=dp[i-1][j];
}
else
{
dp[i][j]=dp[i][j-1];
}
}
}
}
return dp[m][n];
}
int main()
{
//char str1[]={'q','w','e','r','t','y','u'};
//char str2[]={'q','s','e','d','f','r','g','u'};
char str1[]="qwertyuiop";
char str2[]="qsedfrgul";
int res ;
res = LongestCommonSubquence(str1,str2);
cout<<"最长公共子序列的长度是:"<<res<<endl;
}
结果如下: