leetcode10. 正则表达式匹配

该文章探讨了一种从右往左进行字符串匹配的动态规划算法。通过分析不同情况,如字符匹配、通配符*的处理,建立状态转移方程,实现字符串s和模式p的高效匹配。关键在于处理字符不匹配以及*出现时的情况,包括*是否匹配0个字符、1个字符或多个字符的情况。
摘要由CSDN通过智能技术生成

首先左神的代码是从递归暴力开始慢慢优化到动态规划的。而且是从左到右做匹配。

以下代码是直推的方式。
思路:从右往左匹配更合理,也就是当两个串的最后的字符匹配,剩余字符也匹配(动态规划已知),就匹配。
三种大情况:

(为什么是i-1而不是i?可能0到i-1就是i个字符?)
当s[i-1] 和 p[j-1]匹配时,这个串是否匹配看s[0:i-1]和p[0:j-1]是否匹配就行。匹配dp[i][j]存true,不匹配dp[i][j]存false

当s[i-1] 和 p[j-1]不匹配时,不意味着s和p不匹配。因为当p[j-1]是“”时还是有可能匹配的。
当p[j-1]不是,可能不匹配。
当p[j-1]是
,要分情况讨论:
第一种是当p[j-2] 匹配了s[i-1] ,要考虑三种情况,因为p[j-2] 可以消失,存在一次,存在多次,其中有一种匹配都是匹配的。
1、 p[j-2]消失的情况下,也就是考察s[0:j-1]和p[0:j-2],即dp[j-1][j-2]
2、p[j-2]存在一次,也就是考察s[0:j-2]和p[0:j-2],即dp[j-2][j-2]
3、p[j-2]存在多次,其实也是考察s[0:j-2]和p[0:j-2],即dp[j-2][j-2]?

第二种是当p[j-2] 没匹配了s[i-1] ,但是这样还是有可能匹配。此时看p[j-3]和s[i-1]是否匹配。
第三种是当

class Solution:
    def isMatch(self, s: str, p: str) -> bool:
        # dp[0][0]代表s为空串,p为空串,是否匹配。
        dp = [[False for j in range(len(p) + 1)] for i in range(0, len(s) + 1)]
        # base case: 
        dp[0][0] = True
        for j in range(1, len(dp[0])):
            if p[j-1] != "*":
                dp[0][j] = False
            else:
                if j >= 2:
                    dp[0][j] = dp[0][j-2]
        # print(dp)

           

        for i in range(1, len(dp)):
            for j in range(1, len(dp[i])):
                if s[i-1] == p[j-1] or p[j-1] == ".":  # 当最后一个字符和pattern的最后一个字符匹配了
                    dp[i][j] = dp[i-1][j-1]
                elif p[j-1] != "*":  # and s[i] != p[j] and p[j] != "."  当最后一个字符和pattern的最后一个字符没匹配而且pattern的最后一个字符不是*
                    dp[i][j] = False
                else:  # and s[i] != p[j] and p[j] == "*"   当最后一个字符和pattern的最后一个字符没匹配,但是pattern的最后一个字符是*
                    # 看s的最后一次字符和pattern倒数第二个字符是否匹配,
                    # 如果不匹配,那就取决于p的倒数第三个数以前的匹不匹配s全部的了。
                    if s[i-1] != p[j-2] and p[j-2] != ".":                        
                        if j >= 2:
                            dp[i][j] = dp[i][j-2]
                    # 如果匹配,那就看取多少个了。可能取0个,1个,和多个,取0个意味着p倒数第二个匹配了但也删除,那就取决于p的倒数第三个了
                    # 1个,和多个的情况一样,都是取决于s的倒数第二个数以前的和p整个有没有匹配。
                    else:
                        dp[i][j] = dp[i-1][j] or dp[i][j-2]                   
        return dp[-1][-1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值