Bootstrap

面试题 19. 正则表达式匹配

题目描述

请实现一个函数用来匹配包含.*正则表达式。模式中的字符.表示任意一个字符,而*表示它前面的字符可以出现任意次(含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。

示例

例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但与"aa.a"和"ab*a"均不匹配。

题解

记忆化搜索

我们设计一个函数dfs(i, j),表示从s的第i个字符开始和p的第j个字符开始进行匹配,返回值即是否匹配,那么本题答案就是dfs(0, 0)
函数dfs(i, j)计算过程如下:
m = s.size(), n = p.size()

  • 如果j到达了p的末尾且i到达了s的末尾,匹配成功。
  • 如果j的下一个字符是*
    • 匹配0个字符,即dfs(i, j+2)
    • 如果i < ms[i]p[j]匹配,匹配1个字符,即dfs(i+1, j)
  • 如果j的下一个字符不是*
    • 如果i < ms[i]p[j]匹配,即dfs(i+1, j+1),否则匹配失败
    bool regular_expression_match(string str, string pending_match_str) {
        int m = str.size(), n = pending_match_str.size();
        vector<vector<bool>> table(m, vector<bool>(n));
        function<bool(int, int)> match = [&](int i, int j) -> bool {
            if (j >= n) {
                return i == m;
            }
            if (table[i][j]) {
                return table[i][j] == true;
            }
            bool res = false;
            if (j+1 < n && pending_match_str[j+1] == '*') {
                if (match(i, j+2) or (i < m && (str[i] == pending_match_str[j] || pending_match_str[j] == '.') &&
                                        match(i+1, j))) {
                    res = true;
                }
            } else if (i < m && (str[i] == pending_match_str[j] or pending_match_str[i] == '.') && match(i+1, j+1)) {
                res = true;
            }
            table[i][j] = res;
            return res == true;
        };
        match(0, 0);
    }
;