Regular Expression Matching
题目描述:
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). The function prototype should be: bool isMatch(const char *s, const char *p) Some examples: isMatch("aa","a") → false isMatch("aa","aa") → true isMatch("aaa","aa") → false isMatch("aa", "a*") → true isMatch("aa", ".*") → true isMatch("ab", ".*") → true isMatch("aab", "c*a*b") → true
这道题难度等级:Hard。我看了提示,说要使用Dynamic Programming、Backtracking。恶补了一下这两个方面的知识,结果还是没做出来。后来想到了递归,大体思路已经正确,可是细节之处总是处理不好。此题,寡人败了。
我查阅了很多文章,下面的解法在简洁性和易懂性上,无人能出其右。
solution1:(递归)
bool isMatch(const char *s, const char *p) { if (!*p) return (!*s); if ('*' == *(p + 1)) { // x* matches empty string or at least one character: x* -> xx* // *s is to ensure s is non-empty return (isMatch(s, p + 2) || *s && (*s == *p || '.' == *p) && isMatch(s + 1, p)); } else { if (!*s) return false; return (*s == *p || '.' == *p) ? isMatch(s + 1, p + 1) : false; } }
solution2:(动态规划)
bool isMatch(const char *s, const char *p) { int i, j; int m = strlen(s); int n = strlen(p); /** * b[i + 1][j + 1]: if s[0..i] matches p[0..j] * if p[j] != '*' * b[i + 1][j + 1] = b[i][j] && s[i] == p[j] * if p[j] == '*', denote p[j - 1] with x, * then b[i + 1][j + 1] is true if any of the following is true * 1) "x*" repeats 0 time and matches empty: b[i + 1][j -1] * 2) "x*" repeats 1 time and matches x: b[i + 1][j] * 3) "x*" repeats >= 2 times and matches "x*x": s[i] == x && b[i][j + 1] * '.' matches any single character */ //bool b[m + 1][n + 1]; vector< vector<int> > b(m+1,vector<int>(n+1)); b[0][0] = true; for (i = 0; i < m; i++) { b[i + 1][0] = false; } // p[0..j - 2, j - 1, j] matches empty iff p[j] is '*' and p[0..j - 2] matches empty b[0][1] = false; for (j = 1; j < n; j++) { b[0][j + 1] = '*' == p[j] && b[0][j - 1]; } for (i = 0; i < m; i++) { for (j = 0; j < n; j++) { if (p[j] != '*') { b[i + 1][j + 1] = b[i][j] && ('.' == p[j] || s[i] == p[j]); } else { b[i + 1][j + 1] = b[i + 1][j - 1] && j > 0 || b[i + 1][j] || b[i][j + 1] && j > 0 && ('.' == p[j - 1] || s[i] == p[j - 1]); } } } return b[m][n]; }
原文链接:https://oj.leetcode.com/discuss/18970/concise-recursive-and-dp-solutions-with-full-explanation-in