剑指offer 19-正则表达式匹配 C++

题目描述
请实现一个函数用来匹配包括’.‘和’‘的正则表达式。模式中的字符’.‘表示任意一个字符,而’'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但是与"aa.a"和"ab*a"均不匹配。

思路1:递归,参考剑指offer书上解法。

class Solution {
public:
	bool match(char* str, char* pattern)
	{
		if (str == nullptr || pattern == nullptr) return false;
		return matchSub(str, pattern);
	}
	bool matchSub(char* str, char* pattern) {
		if (*str == '\0'&&*pattern == '\0') return true;
		if (*str != '\0'&&*pattern == '\0') return false;   // *str == '\0'&&*pattern != '\0'  用例:"",".*" 为true
		if (*(pattern + 1) == '*') {
			if (*pattern == *str || (*pattern == '.'&& *str != '\0')) 
				return matchSub(str + 1, pattern + 2)
					|| matchSub(str + 1, pattern)
					|| matchSub(str, pattern + 2);
			else
				return matchSub(str, pattern + 2);
		}
		if (*pattern == *str || (*pattern == '.'&& *str!='\0')) 
			return matchSub(str + 1, pattern + 1);

		return false;
	}
};

思路2:含有重叠子问题,考虑动态规划

class Solution {
public:
	bool match(string str, string pattern)
	{
		if (pattern.empty()) return str.empty();
		str = " " + str;   //前面加某一相同字符,防止aa a* 或者ab c*ab这样的匹配,避免复杂的初始化操作
		pattern = " " + pattern;
		vector<vector<bool>> dp(str.size() + 1, vector<bool>(pattern.size() + 1, false));
		dp[0][0] = true;
		for (int i = 1; i < str.size()+1; i++) {  
			for (int j = 1; j < pattern.size()+1; j++) {
				if (pattern[j - 1] == '.' || pattern[j - 1] == str[i - 1])  
					dp[i][j] = dp[i - 1][j - 1]; 
				else if (pattern[j - 1] == '*') {
					if (pattern[j - 2] != str[i - 1] && pattern[j - 2] != '.')   
						dp[i][j] = dp[i][j - 2];   //匹配0次  aaa ab*aa
					else
						dp[i][j] = dp[i - 1][j]  //匹配多次 aaaa aa*a  -> 转换为匹配0次
							|| dp[i][j - 2];   //匹配0次 aaa aa*a
				}
			}
		}
		return dp[str.size()][pattern.size()]; //返回最后字符的匹配状态
	}
};

总结:

  1. 如果 p[j] == s[i] : dp[i][j] = dp[i-1][j-1]
  2. 如果 p[j] == ‘.’ : dp[i][j] = dp[i-1][j-1]
  3. 如果 p[j] == ‘*’ :
    1> 如果 p[j-1] != s[i] : dp[i][j] = dp[i][j-2]
    2> 如果 p[j-1] == s[i] || p[j-1] == ‘.’:
    1. dp[i][j] = dp[i-1][j] 匹配多次
    2. dp[i][j] = dp[i][j-2] 匹配0次

你可能感兴趣的:(动态规划,C++)