【递归与动态规划】正则表达式匹配

https://leetcode-cn.com/problems/regular-expression-matching/

1. 递归思想

如果p 为空,s为也为空。则匹配成功。

s、p为当前字符。如果*s == *p或者 *p == '.',则当前字符是匹配的。

如果p的下一个字符串为'', 如果对s的当前字符匹配零次,则p的指针向后移动两步,继续递归;如果s == p, 并p通过''匹配s中的多个字符,则s的指针向后移动一步,继续递归。

否则,如果s和p的当前字符匹配,那么s和p的指针都向后移动一步,继续递归。

class Solution {
public:
    bool isMatch(string s, string p) {
        return match(s.c_str(),p.c_str()); 
    }

    bool match(const char* s, const char* p){ //
        if(*p == 0) return *s == 0;
        bool first_char_match = *s && (*s == *p || *p == '.');
        if(*(p + 1) == '*'){  
            return match(s, p+2) || (first_char_match && match(++s, p)); 
        }else{
            return first_char_match && match(++s, ++p);
        }
    }
};

2. 通过动态规划优化

用dp[i][j]表示s[0...i-1]和p[0...j-1]是否正则匹配。

如果p[j-1]是'*',

  • 如果对p[j-2]匹配0次,则dp[i][j] = dp[i][j-2]
  • 如果p[j-2] == s[i-1], 并对p[j-2]匹配1次或多次,则dp[i][j] = dp[i-1][j]

如果p[j-1] == s[i-1] 或 p[j-1] == '.':

  • 则p[i][j] = p[i-1][j-1]
class Solution {
public:
    bool isMatch(string s, string p) {
        int sSize = s.size();
        int pSize = p.size();
        vector<vector<int>> dp(sSize + 1, vector<int>(pSize + 1));
        dp[0][0] = true;

        auto match = [&](int i , int j){
            return  i > 0 && (p[j - 1] == '.' || s[i -1] == p[j -1]);
        };

        for(int i = 0; i < sSize + 1; ++i){
            for(int j = 1; j < pSize + 1; ++j){
                if(p[j - 1] == '*'){
                    dp[i][j] |= dp[i][j-2];
                    if(match(i, j - 1)){
                        dp[i][j] |= dp[i -1][j];
                    }
                }else if(match(i, j)){
                    dp[i][j] |= dp[i-1][j-1];
                }
            }
        }   
        return dp[sSize][pSize];
    }
};

posted on 2022-01-06 17:14  七昂的技术之旅  阅读(38)  评论(0编辑  收藏  举报

导航