传送门:https://leetcode-cn.com/problems/regular-expression-matching/
题目
给你一个字符串
s和一个字符规律p,请你来实现一个支持'.'和'*'的正则表达式匹配。
'.':匹配任意单个字符'*':匹配零个或多个前面的那一个元素 所谓匹配,是要涵盖整个字符串s的,而不是部分字符串。
示例 1:
输入:s = “aa” p = “a” 输出:false 解释:”a” 无法匹配 “aa” 整个字符串。
示例 2:**
输入:s = “aa” p = “a“ 输出:true 解释:因为 ‘‘ 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 ‘a’。因此,字符串 “aa” 可被视为 ‘a’ 重复了一次。
示例 3:**
输入:s = “ab” p = “.“ 输出:true 解释:”.“ 表示可匹配零个或多个(’*’)任意字符(’.’)。
示例 4:**
输入:s = “aab” p = “cab” 输出:true 解释:因为 ‘*’ 表示零个或多个,这里 ‘c’ 为 0 个, ‘a’ 被重复一次。因此可以匹配字符串 “aab”。
示例 5:
输入:s = “mississippi” p = “misisp*.” 输出:false
阿巴阿巴 ….大家好,我是老实巴交的老实人,得知大家都用动态规划做的我人傻了。
代码
我的代码
class Solution {public:bool clearOne(string p) {//空串返回falseint p_len = p.length();int pp = 0;if (p.empty() || p == "")return false;if (((pp + 1) < p.length()) && (p.at(pp + 1) == '*')) return true;return false;}bool check_pnull(string p) {//判断规则p剩余部分是否可以抵消int p_len = p.length();int pp = 0;if (p.empty() || p == "")return true;while (pp < p_len) {//字母在if (pp + 1 < p_len) {//*号在if (p.at(pp + 1) == '*')//*匹配pp += 2;elsereturn false;}else {//*号不在if (p.at(pp) == '*')return true;return false;}}return true;}bool isMatch(string s, string p) {int s_len = s.length();int p_len = p.length();//二者长度int sp, pp;//哨兵sp = pp = 0;//初始化if ((!s.empty()) && (p.empty() || p == ""))return false;if (!p.empty() && (s.empty() || s == "")) {if (check_pnull(p))return true;return false;}//去除非法情况和特殊空串情况while (sp < s_len || pp < p_len) {while ((sp < s_len && pp < p_len) && s.at(sp) == p.at(pp)) {//二者相等就顺着排sp++; pp++;}//匹配就下行//出来有可能是不匹配也有可能是超过长度//1不匹配if (sp < s_len && pp < p_len) {//确保在长度内if (p.at(pp) == '.') {//.类型不匹配sp++; pp++;}else if (p.at(pp) == '*') {//*类型不匹配bool real = false;int temp_sp = sp - 1;//第一种先消去*前面的来跟s匹配if (pp + 1 < p_len)//未越界情况才有可能消去,越界一定不用消除real= isMatch(s.substr(temp_sp, s_len - temp_sp), p.substr(pp + 1, p_len - pp - 1));if (real)return true;//第二种到底匹配几个的问题if ((sp < s_len && pp + 1 < p_len)) {//*只匹配一次real = isMatch(s.substr(sp, s_len - sp), p.substr(pp + 1, p_len - pp - 1));if (real)return true;}while ((sp < s_len && pp < p_len)) {//从第2此开始依次匹配if ((s.at(sp) == p.at(pp - 1)) || p.at(pp - 1) == '.') {sp++;if ((sp < s_len && pp + 1 < p_len)) {real = isMatch(s.substr(sp, s_len - sp), p.substr(pp + 1, p_len - pp - 1));if (real)return true;}}else {pp++;break;}}// pp++;}else {if ((pp + 1 < p_len) && (p.at(pp + 1) == '*')) {//还有救pp += 2;}elsereturn false;}}else {//2超出长度//如果二者同时超出了长度则说明匹配成功//若是单独一方超出则要看情况//a. 若p超出了长度,说明s串还有未比配的数,一定不匹配//b. 若s超出了长度,说明要回溯,两种检查,剩下p是否能check_pnull,若能则匹配,若不能则claenOne弄掉一对让s的最后一个字母与剩下的p规则匹配if (sp == s_len && pp == p_len) {//二者同时超出了长度则说明匹配成功return true;}else {//单独一方超出if (pp >= p_len)return false;//aif (sp >= s_len) {//bif (p.at(pp) == '*') {if (check_pnull(p.substr(pp + 1, p_len - pp))) return true;//剩下的能消除else {//不能消除if (clearOne(p.substr(pp - 1, p_len - pp + 1))) {sp--;pp = pp + 1;return isMatch(s.substr(sp, s_len - sp), p.substr(pp, p_len - pp));}else return false;}}else {if (check_pnull(p.substr(pp, p_len - pp))) return true;//剩下的能消除else {//不能消除if (clearOne(p.substr(pp - 1, p_len - pp + 1))) {sp--;pp = pp + 1;return isMatch(s.substr(sp, s_len - sp), p.substr(pp, p_len - pp));}else return false;}}}}}}if (sp == s_len && pp == p_len)return true;elsereturn false;}};
