动态规划动态匹配思想详解 —— 最大公共子串问题

最近遇到很多这种类型的题目,都是需要用到动态规划解决的,在此将这一类型的题目都更新出来,方便大家和我一起学习 ^ _ ^
.
相关博文链接:
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:
在这里插入图片描述

此处已经结束了,下面我就不一一演示了,大家可以自行测试 . . .


.

浪子花梦

一个有趣的程序员 ~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章