[AcWing30]正则表达式匹配

[AcWing30]正则表达式匹配

请实现一个函数用来匹配包括'.''*'的正则表达式。
模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(含0次)。
例如,字符串"aaa"与模式"a.a""ab*ac*a"匹配,但是与"aa.a""ab*a"均不匹配。

class Solution{
public:
    bool isMatch(string s, string p){
        
    }
};

题目并没有给出数据范围

一篇良心题解

设令 \(s\) 长度为 \(n\) , \(p\) 长度为 \(m\) , \(f[i][j]\) 表示 \(p[j,m]\) 能否匹配 \(s[i,n]\)
\(1.\) 如果 \(p[j+1]\) \(!=\) '\(*\)' , 则 \(f[i][j]\) 为真当且仅当 \(s[i]\) 可以和 \(p[j]\) 匹配 , 且 \(f[i+1][j+1]\) 为真 .
\(2.\) 如果 \(p[j+1]\) \(==\) '\(*\)' , 则 \(f[i][j]\) 有以下两种情况可以为真 :
"\(*\)" 代表 \(0\)\(p[j]\) , 等价于 \(f[i][j+2]\) 为真 ;
"\(*\)" 代表若干个 \(p[j]\) , 等价于 $f[i+1][j] $ 为真而且 \(s[i]\) 可以和 \(p[j]\) 匹配
然后就可以用记忆化了 , 一共 \(nm\) 个状态 , 时间复杂度 \(O(nm)\) .

class Solution{
public:
    vector<vector<int>> f;
    int n, m;
    bool isMatch(string s, string p){
        n = s.size(), m = p.size();
        f = vector<vector<int>>(n + 1, vector<int>(m + 1, -1));
                          // f = n+1个 ((m+1个-1)组成的vector)
        return dp(0, 0, s, p);
    }
    inline bool dp(int x, int y, string& s, string& p){
        if(x > n || y > m) return 0;
        if(f[x][y] != -1) return f[x][y];
        if(y == m)
            return f[x][y] = (x ==n);
        bool now_match = ((s[x] == p[y]) || (p[y] =='.'));
        bool ans;
        if(p[y + 1] == '*')
            ans = dp(x, y + 2, s, p) || (now_match && dp(x + 1, y, s, p));
        else
            ans = now_match && dp(x + 1, y + 1, s, p);
        return f[x][y] = ans;
    }
};

一道锻炼思维的好题 , \(DP\) 思维最能体现一个人的水平 .

猜你喜欢

转载自www.cnblogs.com/lizehon/p/11200149.html