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

该博客探讨如何使用C++实现正则表达式的匹配功能,涉及'.'表示任意字符,'*'表示前一字符可重复任意次的规则。通过两种思路——递归和动态规划,解决匹配问题。文中总结了关键的匹配条件,如当模式字符等于或为'.'时的处理,并详细解释了'*'字符的两种情况。
摘要由CSDN通过智能技术生成

题目描述
请实现一个函数用来匹配包括’.‘和’‘的正则表达式。模式中的字符’.‘表示任意一个字符,而’'表示它前面的字符可以出现任意次(包含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次
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值