首先我们来区分一下子序列和子串:
子串是连续的,子序列是一个字符串中删除若干元素后形成的(两个元素前后相对顺序不变)
子序列包含子串
例:str = abcdefg
子串:cde
子序列:acf
问题 F: 最长公共子序列
题目描述
一个字符串A的子串被定义成从A中顺次选出若干个字符构成的串。如A=“cdaad" ,
顺次选1,3,5个字符就构成子串" cad" ,现给定两个字符串,求它们的最长共公子串长度
输入
第一行两个字符串用空格分开。两个串的长度均小于2000 。
输出
最长子串的长度。
样例输入
abccd aecd
样例输出
3
之前说过,每种动态规划解决方案都涉及网格
(第一行和第一列之前还有一行一列,都是0)
#include <iostream>
#include <cstring> //要用到字符串函数strlen()
using namespace std;
char a[2000];
char b[2000];
int maxlen[2000][2000];
int main()
{
cin >> a >> b;
int len1 = strlen(a);
int len2 = strlen(b);
//第一行和第一列全置零(不涉及字母的行列)
for (int i = 0; i <= len1; i++)
{
maxlen[i][0] = 0;
}
for (int j = 0; j <= len2; j++)
{
maxlen[0][j] = 0;
}
for (int i = 1; i <= len1; i++) //逐行比较字符
{
for (int j = 1; j <= len2; j++) //i=0,j=0的地方都是0
{
if (a[i - 1] == b[j - 1]) //这里i,j都是1开始,但字符串都是0开始,i-1就代表第i个字符
{
maxlen[i][j] = maxlen[i - 1][j - 1] + 1; //这里的i-1,j-1代表左上邻居
}
else //两个字符不相等
{
if (maxlen[i - 1][j] >= maxlen[i][j - 1]) //左边邻居和上边邻居哪个大等于哪个
{
maxlen[i][j] = maxlen[i - 1][j];
}
else
{
maxlen[i][j] = maxlen[i][j - 1];
}
}
}
}
cout << maxlen[len1][len2] << endl;
return 0;
}
上算法课时做的例题: