leetcode10.(力扣)正则表达式匹配

(一)递归方法
具体参考:https://blog.csdn.net/qq_28410301/article/details/100182901

对于匹配的p字符串有三种情况:
①c=‘.’ ; 可以匹配任何一个字符
②c=‘*’;在一个字符后边,表示可以重复0-n次这个字符
③c=普通字符
第一种和第三种情况都很好处理,重要的是第二种情况。

第二种情况分为:
①匹配前面的字符0次,将这个字符和*一起跳过,继续调用isMatch()
②匹配前面的字符多次。比较首元素,如果相同,s的元素+1,保持p不变继续调用isMatch()

p空:如果s空,返回true;如果s不空,返回false
p不空:①第二个元素是’‘,isMatch(s,p.substr(2))(重复字符匹配0次);
②p第一个元素和s串里的第一个元素匹配并且p的第二个元素是’
',isMatch(s.substr(1),p)(跳过s第一个元素,继续进行剩下元素的匹配)
③如果第二个元素不是‘*’,进行正常顺序匹配,并且isMatch(s.substr(1),s.substr(1))进行接下来的匹配

class Solution {
public:
    bool isMatch(string s, string p) {
        // 在p为空后 只需要查看s是否为空即可
        if (p.empty()) {
            return s.empty();
        }
        // 查看首元素是否一致
        bool first_match = !s.empty() && (s[0] == p[0] || p[0] == '.');
        // 如果下一个字符是'*'
        if (p.size() >= 2 && p[1] == '*') {
            return (bool)( isMatch(s, p.substr(2)) || (first_match && isMatch(s.substr(1), p)));
        }
       // 一般情况
        else {
            return bool( first_match && isMatch(s.substr(1), p.substr(1)));
        }
    }
};

(二)动态规划
每一次匹配都是基于之前的匹配结果,所以可以自然的想到动态规划的开始是两个空串可以相互匹配,所以搭建dp[i][j]的二维数组并且dp[0][0]为true。

在这里插入图片描述

class Solution {
public:
    bool isMatch(string s, string p) {
        int n = s.size(), m = p.size(); //dp[i][j]表示s[0...i)与p[0...j)是否匹配
        vector<vector<bool>> dp(n + 1, vector<bool>(m + 1, false));
        dp[0][0] = true; //表示s[0,0)与p[0,0)匹配
        for (int i = 1; i <= n; ++i) dp[i][0] = false; //表示s[0,i)与p[0,0)不匹配
        for (int i = 1; i <= m; ++i) {
            if (p[i - 1] != '*') dp[0][i] = false; //表示s[0,0)与p[0,i)不匹配
            else dp[0][i] = dp[0][i - 2]; //表示s[0,0)与p[0,i)匹配结果,由s[0,0)与p[0,i-2)匹配的结果决定
        }
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= m; ++j) {
                if (s[i - 1] == p[j - 1] || p[j - 1] == '.') dp[i][j] = dp[i - 1][j - 1]; //此处匹配
                else if (p[j - 1] == '*') //字符匹配且s[0,i-1)与p[0,j)匹配(匹配1次到多次) 或 s[0,i)与p[0,j-2)匹配(匹配0次)
                    dp[i][j] = (((s[i - 1] == p[j - 2] || p[j - 2] == '.' ) && dp[i - 1][j]) || dp[i][j - 2]); 
                else dp[i][j] = false;
            }
        }
        return dp[n][m];
    }  
};

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
正则表达式匹配是一个经典的算法问题,主要是判断一个字符串是否能够完全匹配给定的正则表式。 在LeetCode上,也有一道关于正则表达式匹配的题目,题目编号是10。这道题目要求实现一个支持 '.' 和 '*' 的正则表达式匹配,其中 '.' 可以匹配任意单个字符,'*' 可以匹配零个或多个前面的元素。 解决这道题可以使用动态规划的思想,具体的思路如下: 1. 创建一个二维数组dp,dp[i][j]表示s的前i个字符与p的前j个字符是否匹配。 2. 初始化dp为true,表示空字符串与空正则表达式是匹配的。 3. 初始化dp[i]为false,表示非空字符串与空正则表达式是不匹配的。 4. 初始化dp[j],如果p[j-1]是"*",则dp[j]的值取决于dp[j-2]的值,表示将p[j-2]与p[j-1]去掉后的正则表达式是否匹配空字符串。 5. 对于其它的dp[i][j],分成两种情况: - 如果p[j-1]是"."或者与s[i-1]相等,则dp[i][j]的值取决于dp[i-1][j-1]的值,表示将s[i-1]和p[j-1]去掉后的字符串是否匹配。 - 如果p[j-1]是"*",则dp[i][j]的值取决于以下两种情况: - dp[i][j-2]的值,表示将p[j-2]和p[j-1]去掉后的正则表达式是否匹配s的前i个字符。 - dp[i-1][j]的值,表示将s[i-1]与p[j-2]匹配后的字符串是否匹配p的前j个字符。 6. 最后返回dp[s.length()][p.length()]的值,表示整个字符串s与正则表达式p是否完全匹配。 以上是一种使用动态规划解决正则表达式匹配问题的思路,具体的实现可以参考LeetCode官方提供的递归思路的解法。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [LeetCode算法 —— 正则表达式匹配(详解官方动态规划思想)](https://blog.csdn.net/weixin_42100963/article/details/106953141)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值