10. 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
@首先题目要理解,通配符*是重复前面一个元素,而不是*前面所有的元素而且通配符*号前面必须要有元素,就是说*出现的位置不可能在第一位。
f[i][j] = f[i][j - 2] || (s[i - 1] == p[j - 2] || '.' == p[j - 2]) && f[i - 1][j];

f[i][j - 2]表示前面的元素出现0次,后面表示出现次数大于等于1.

aabbb

aab.*

能够出现多次,说明s中减少一个(i -1)也能匹配,所以这个条件也必须满足。

s[i - 1] == p[j - 2]因为ij表示出现的元素个数,相当于下标从i - 1,j - 1.
表示p中倒数第二个元素要和s中倒数第一个元素相等。这样才能进行重复。
注意初始化第一列的情况。
class Solution {
public:
    bool isMatch(string s, string p) {
        if(s.size() == 0 && p.size() == 0){
            return true;
        }
        int m = s.size();
        int n = p.size();
        vector<vector<bool>> dp(m + 1,vector<bool> (n + 1,false));
        
        dp[0][0] = true;
        for(int i = 1;i <= m;++i){
            dp[i][0] = false;
        }
        for(int j = 1;j <= n;++j){
            if((j > 1) && (j % 2 == 0) && dp[0][j - 2] && p[j - 1] == '*'){
                dp[0][j] = true;
            }
        }
        
        for(int i = 1;i <= m;++i){
            for(int j = 1;j<= n;++j){
                if(p[j - 1] != '*'){
                    dp[i][j] = dp[i - 1][j - 1] && (s[i - 1] == p[j - 1] || '.' == p[j - 1]);
                }
                else{
                    dp[i][j] = dp[i][j - 2] || dp[i - 1][j] && ((s[i - 1] == p[j - 2]) || '.' == p[j - 2]);
                }
            }
        }
        return dp[m][n];
    }
};
原文地址:https://www.cnblogs.com/dingxiaoqiang/p/7739913.html