10.正则表达式匹配

思路

动态规划

image-20220810010556502
  1. 字符或'.' + '*'当做一个整体进行处理,因此如果下一个位置是*,那就跳过当前位置

  2. p[j] != '*'时,那就是字符匹配,此时i必须大于0,因为s[i]必须是一个字符才能进行匹配

    1. 此时dp[i][j] = dp[i - 1][j - 1] && (s[i] == p[j] || p[j] == '.');,即s[1~i]p[1~j]匹配 等于 s[1~i-1]p[1~j-1]匹配以及s[i]p[j]匹配
  3. p[j] == '*'时,*可以表示任意个p[j - 1]字符,

    *表示0个p[j - 1],那就是F(i, j) = F(i, j - 2),即s[1~i]和p[1~j-2]匹配

    *表示1个p[j - 1],那就是F(i, j) = F(i - 1, j - 2) && s[i] == [j - 1]
    s[1~i - 1]p[1~j-2]匹配,且s[i] == p[j - 1]

    最后dp[i][j] == 上述所有结果的或值

p[j] == '*'状态转移进行优化

dp[i - 1][j] = dp[i - 1][j - 2];
             = dp[i - 2][j - 2] && s[i-1] == p[j-1]
             = dp[i - 3][j - 2] && (s[i-1] == p[j-1] && s[i] == p[j-1])

显然dp[i - 1][j]跟第二个转移方程的差别是dp[i][j - 2]s[i]==p[j-1] ,因此原方程可转换成

\(F(i, j) = f(i, j-2) || {f(i-1, j) \& s[i] == p[j - 1] }\)

代码

class Solution {
public:
    bool isMatch(string s, string p) {
        s = ' ' + s, p = ' ' + p;
        int n = s.size(), m = p.size();
        vector<vector<bool>> dp(n, vector<bool>(m));
        dp[0][0] = true;
      	// i从0开始,因为空字符串和a*是匹配的
        for(int i = 0; i < n; i++)
            for(int j = 1; j < m; j++)
            {
                if(j + 1 < m && p[j + 1] == '*') continue;
                if(i && p[j] != '*') 
                  dp[i][j] = i && dp[i - 1][j - 1] && (s[i] == p[j] || p[j] == '.');
                else if(p[j] == '*') 
                  dp[i][j] = dp[i][j - 2] || i && dp[i - 1][j] && (s[i] == p[j - 1] || p[j - 1] == '.');
            }
        return dp[n - 1][m - 1];
    }
};
posted @ 2022-11-08 13:52  INnoVation-V2  阅读(39)  评论(0编辑  收藏  举报