最近遇到很多这种类型的题目,都是需要用到动态规划解决的,在此将这一类型的题目都更新出来,方便大家和我一起学习 ^ _ ^
.
相关博文链接:
LeetCode算法 —— 正则表达式匹配(详解官方动态规划思想)
题目:
最大公共子串长度问题就是:
求两个串的所有子串中能够匹配上的最大长度是多少。
比如:“abcdsdjflkas” 和 “abdabcdd”,
可以找到的最长的公共子串是"abcd", 所以最大公共子串长度为4。
解题思想:此题和前文的正则表达式匹配的思想是差不多的,都是使用一个二维数组当作一个标志存储容器,arr[i][j] 表示 Str 中的第 i 个字符是否和 SubStr 中的第 j 个字符相同,如若相同,并且 arr[i - 1][j - 1] 也相同,则我们将它们作上一个数字上的标记,用来表明最大子串长度是多少 . . .
比如我们开辟一个数组大小是 12 * 12,里面的每一个元素都是 两个串中元素的对应关系
例如这个图如下所述:
代码如下所示:
#include <iostream>
#include <vector>
using namespace std;
class Solution {
public:
int GetMaxSubStr(string Str, string subStr) {
int iSize = Str.size();
int jSize = subStr.size();
int len = iSize > jSize ? iSize : jSize; // 找出比较长的串的大小
int MaxSize = 0; // 最大的公共子串大小
// 动态规划思想
vector<vector<int> > arr(len + 1, vector<int>(len + 1));
for (size_t i = 1; i <= iSize; i++)
{
for (size_t j = 1; j <= jSize; j++)
{
// 判断当前匹配的字符是否相等
if (Str[i - 1] == subStr[j - 1])
{
// 当前的匹配结果 等于前一个字符 i - 1 j - 1 匹配结果 + 1
arr[i][j] = arr[i - 1][j - 1] + 1;
if (MaxSize < arr[i][j]) // 时刻更新最大的公共子串大小
MaxSize = arr[i][j];
}
}
}
return MaxSize; // 返回最大值
}
}
测试代码就不演示了,这里的代码不长,并且非常的有趣,简单的几行代码就可以把这个字符串之间的关系给搞清楚 . . .
这里的核心代码只有一句:
arr[i][j] = arr[i - 1][j - 1] + 1;
如果看懂的小伙伴可以直接点赞关闭了,哈哈 ^ _ ^
我们可以这样理解: 比如 abcd 和 abXX 这两个串,现在的 arr[i][j] 中的 i 表示第一个串 b 这个字符, j 表示第二个串 b这个符,现在我们判断完这两个字符是相等的,然后我们执行上面的这条语句,
在 b 与 b 判断相等之前,我们已经把 a 与 a 判断成功了
,也就是现在的 arr[i - 1][j - 1] 这个标志已经有值了,假设这个值为 1(当前的目标也确实是 1),所以我们的 arr[i][j] 的值现在是 1 + 1 == 2
单个匹配图解过程
我们将每一个 Str中的字符 与 SubStr中的所有字符进行匹配之后产生的图如下所示:
1)Str 中的 a:
2)Str 中的 b:
3)Str 中的 c:
3)Str 中的 d:
此处已经结束了,下面我就不一一演示了,大家可以自行测试 . . .
.