- 用递归的算法
-
static const auto __speedup_ = []() { std::cout.sync_with_stdio(false); std::cin.tie(nullptr); return 0; }(); /* 用递归的算法:注意边界条件的讨论 原问题如下: Given an input string (s) and a pattern (p), implement regular expression matching with support for '.' and '*'. '.' Matches any single character. '*' Matches zero or more of the preceding element. The matching should cover the entire input string (not partial). Note: s could be empty and contains only lowercase letters a-z. p could be empty and contains only lowercase letters a-z, and characters like . or *. */ class Solution { public: // 用p匹配s bool isMatch(string s, string p) { // p为空时的讨论 if (!p.length() && !s.length()) return true; if (!p.length() && s.length() > 0) return false; // s为空时的讨论,只有p为 .*.*.*.*.* 的形式时才能匹配 if (!s.length()) { if (p.length() % 2 == 1) return false; int i = 1; while (i < p.length() && p[i] == '*') { i += 2; } if (i == p.length() + 1) return true; else return false; } // p[1]为*时,用p+2匹配s+0,s+1,s+2,s+3…………,成功返回true,失败返回false int i = -1; if (p.length() >=2 && p[1] == '*') { do { // 当++i为len+1时截取字符串才会越界报错,但是++i为len时截取的子串为空就已经返回结果了,所以永远没有机会截取len+1 if (isMatch(s.substr(++i), p.substr(2))) return true; // 匹配失败且i已经为len了,即p+2匹配到s的最后了任然匹配失败,return false else if (i == s.length()) return false; // 由于上面的++i截取到len时就会return退出,所以s[i]也永远不会越界 } while ((s[i] == p[0] || p[0] == '.')); return false; } // p[1]不为*时 else { if (s[0] == p[0] || p[0] == '.') return isMatch(s.substr(1), p.substr(1)); else return false; } } };
- 用动态规划的算法
-
/* 用动态规划的算法:边界、越界问题最后统一讨论 原问题如下: Given an input string (s) and a pattern (p), implement regular expression matching with support for '.' and '*'. '.' Matches any single character. '*' Matches zero or more of the preceding element. The matching should cover the entire input string (not partial). Note: s could be empty and contains only lowercase letters a-z. p could be empty and contains only lowercase letters a-z, and characters like . or *. */ class Solution { public: // 用p匹配s bool isMatch(string s, string p) { // match[i][j]==true 表示s的前i位和p的前j位是匹配的 vector< vector<bool> > match(s.length() + 3, vector<bool>(p.length() + 3, false)); // 边界条件为i=0 j=0 j=1 // j=0时p为空串,只能匹配空串,其他默认为false match[0][0] = true; // j=1时p只有一个字符,只能匹配一个字符,其他全部为false match[1][1] = s[0] == p[0] || p[0] == '.'; // i=0时s为空串,p只有类似a*b*c*d*这样的形式才可以成功匹配 for (int j = 2; j < p.length() + 1; j += 2) // 前0位和前j-2位是匹配的,且第j位是* match[0][j] = match[0][j - 2] && p[j - 1] == '*'; // i表示s的前i位,j表示p的前j为 for (int i = 1; i < s.length() + 1; i++) for (int j = 2; j < p.length() + 1; j++) { if (p[j - 1] != '*') // 前i-1位和前j-1位是匹配的,且第i位和第j位是匹配的 match[i][j] = match[i - 1][j - 1] && (s[i - 1] == p[j - 1] || p[j - 1] == '.'); else //当p[j-1]出现0次时,前i位和前j-2位是匹配的 //当p[j-1]出现1次或多次时,第i位一定匹配第j-1位,且前i-1位一定和前j位是匹配的。 match[i][j] = match[i][j - 2] || match[i - 1][j] && (s[i - 1] == p[j - 2] || p[j - 2] == '.'); } return match[s.length()][p.length()]; } };
- 1234234
转载于:https://www.cnblogs.com/jkn1234/p/8967415.html