1 题目
Implement regular expression matching with support for ‘.‘
and ‘*‘
实现(implemement)正则表达式,支持.和*
‘.‘ 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
1 分析
难点在于*的处理
*可能做0,1,n来处理
使用s1,s2表示两个字符串的开始位置。
当s2+1 位置是0,并且s1,s2位置的字符相等的时候。
那么就分别处理*是0,1,n的情况
bool solve(string str1, int s1, string p, int s2) { if (str1.size() == s1 && p.size() == s2) { return true; } if (str1.size() < s1 && p.size() == s2) { return false; } // 当下个字符是 * 的时候,那么会存在,* 当 0 ,1,n处理 if (p[s2 + 1] == ‘*‘) { if (str1[s1] == p[s2] || (p[s2] == ‘.‘ && str1.size() != s1)) { // solve(str1, s1 + 1, p, s2 + 2) 是 * 当 1 处理 // solve(str1, s1, p, s2 + 2) 是* 当0处理 // solve(str1, s1 + 1, p, s2) 是 * 当 n 处理,所以str1 动,但是p不懂 return solve(str1, s1 + 1, p, s2 + 2) || solve(str1, s1, p, s2 + 2) || solve(str1, s1 + 1, p, s2); } else { // 如果 str1[s1] == p[s2] 那么 * 一定当0 处理 return solve(str1, s1, p, s2 + 2); } } else { // 不相等的情况下都移动 if (p[s2] == str1[s1] || (p[s2] == ‘.‘ && s1 < str1.size())) { return solve(str1, s1 + 1, p, s2 + 1); } } }
但是上面的方法会超时,应该是处理了大量的子问题?
动态规划的方法:
思想是,使用dp数组,记录str长为i,p长为j时的匹配状况。
因此,当p[j]时*的时候,要分别记录,*按照0,1,n取的情况。
当*按照n取的时候,是要等于dp[i-1][j]的
class Solution { public: bool isMatch(string s, string p) { int m = s.size(), n = p.size(); vector<vector<bool>> dp(m + 1, vector<bool>(n + 1, false)); dp[0][0] = true; for (int i = 0; i <= m; i++) for (int j = 1; j <= n; j++) if (p[j - 1] == ‘*‘) { // =dp[i][j - 2] 表示 * 按照 0处理,也就是p中没有 *前面的字符 // i > 0 && (s[i - 1] == p[j - 2] || p[j - 2] == ‘.‘ 表示 * 当1处理 // 并且 * 当 1 处理的前提是,dp[i - 1][j] 也就是说, // p中前一个已经匹配了 * 前面的字符 dp[i][j] = dp[i][j - 2] || (i > 0 && (s[i - 1] == p[j - 2] || p[j - 2] == ‘.‘) && dp[i - 1][j]); } else { // 当不是*的时候,就需要 p中字符匹配s中字符或是 p 中字符是 . dp[i][j] = i > 0 && dp[i - 1][j - 1] && (s[i - 1] == p[j - 1] || p[j - 1] == ‘.‘); } return dp[m][n]; } };