10. 正则表达式匹配

  1. 题目链接

  2. 解题思路:先写一个暴力递归,bool process(s, p, i, j)s[i...]p[j...]能否匹配成功?,i之前,以及j之前的都已经匹配成功了。

    • 1️⃣p[j + 1] != '*'

      • p[j] == '.',则递归调用process(s, p, i + 1, j + 1)

      • p[j] != s[i],返回false,否则返回process(s, p, i + 1, j + 1)

    • 2️⃣p[j + 1] == '*'

      • p[j] == '.',匹配0个.,即process(s, p, i, j + 2),匹配多个.,即process(s, p, i + 1, j),这两个递归,任意一个返回true,则是true
      • p[j] == s[i],匹配0个s[j],即process(s, p, i, j + 2),匹配多个s[j],即process(s, p, i + 1, j),两个递归,任意一个返回true,则是true,和上面可以合并成一个。
      • p[j] != s[i],只能匹配0个p[j],即process(s, p, i, j + 2)
  3. 有了暴力递归,可以发现,可变参数就是ij,所以可以加dp缓存表。

  4. 代码

    class Solution {
    public:
    // 现在匹配s[i...]以及p[j...],之前的已经匹配ok了,dp是缓存表,0表示false,1表示true,-1表示没有计算
    bool process(string &s, string &p, int i, int j, vector<vector<int>> &dp) {
    if (i == s.length() && j == p.length()) { // 递归终止条件
    return true;
    }
    if (i == s.length()) { // 递归终止条件
    if (j + 1 ==p.length()) {
    return false;
    }
    if (p[j + 1] == '*') {
    return process(s, p, i, j + 2, dp);
    }
    return false;
    }
    if (j == p.length()) {
    return false;
    }
    if (dp[i][j] != -1) {
    return dp[i][j];
    }
    if (j + 1 < p.length()) {
    if (p[j + 1] != '*') {
    if (p[j] == '.') {
    dp[i][j] = process(s, p, i + 1, j + 1, dp);
    return dp[i][j];
    }
    // p[j] != s[i]
    if (p[j] != s[i]) {
    dp[i][j] = false;
    return false;
    }
    // p[j] == s[i]
    dp[i][j] = process(s, p, i + 1, j + 1, dp);
    return dp[i][j];
    }
    // p[j + 1] == '*'
    if (p[j] == '.' || p[j] == s[i]) {
    bool next = process(s, p, i, j + 2, dp); // 匹配0个
    if (next) { // 如果匹配成功了 就不用往下走了
    dp[i][j] = true;
    return true;
    }
    // 匹配多个
    next = process(s, p, i + 1, j, dp);
    dp[i][j] = next;
    return next;
    }
    // p[j] != s[i]
    dp[i][j] = process(s, p, i, j + 2, dp);
    return dp[i][j];
    }
    // j是最后一个字符了
    if (p[j] == '.' || s[i] == p[j]) {
    dp[i][j] = process(s, p, i + 1, j + 1, dp);
    return dp[i][j];
    }
    // s[i] != p[j]
    dp[i][j] = false;
    return false;
    }
    bool isMatch(string s, string p) {
    int n1 = s.length();
    int n2 = p.length();
    vector<vector<int>> dp(n1 + 1, vector<int>(n2 + 1, -1));
    return process(s, p, 0, 0, dp);
    }
    };
posted @   ouyangxx  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示