正则表达式匹配
题目描述:


解题思路:
- 第一种:动态规划。这个方法的思路就是通过判断
dp[i][j],也就是s的前i项和p的前j项是否匹配。后面的dp[a][b]中的a和b就是在字符串和字符规律中的位置。先定义一个dp,全部放入False。先使得dp[0][0] = True这样可以避免都为空的情况,这种情况是可以匹配的。 - 然后我们要明白几点,首先就是
*是和它之前的那个字符有关,也就是a*可以是任何数值的a,当然也可以是0个a。所以如果它为0,那么这个字符规律就少两个字符,如果此时仍能匹配,则也就是如果dp[0][i-1] == True,则可以推出dp[0][i+1] == True,这是一种情况。其次,.这个字符是可以代替任何字符的,但是只能代替一个字符,所以如果在匹配的时候出现了有.的情况,那么相对应另一个字符串的那个位置则可以忽略,因为这两个已经匹配了。最后这里,如果出现*,并且前一个字符对应字符串的字符不同,则说明这个*给前一个字符的数量为0,也就是减少了两个字符,所以dp[a+1][b+1] = dp[a+1][b-1]。如果说相同,那么这个*给的数量就是对应字符的数量,可以全部抵消。最后考虑一些特殊情况,完善就可以了。 - 时间复杂度:O(MN)
class Solution:
def isMatch(self, s: str, p: str) -> bool:
s_len = len(s)
p_len = len(p)
dp = [[False] * (p_len + 1) for _ in range(s_len + 1)]
dp[0][0] = True # 给定一个哨兵节点。
for i in range(p_len):
if p[i] == "*" and dp[0][i-1]:
dp[0][i+1] = True
for a in range(s_len):
for b in range(p_len):
if p[b] == s[a] or p[b] == ".":
dp[a+1][b+1] = dp[a][b]
elif p[b] == "*":
if p[b-1] != s[a]:
dp[a+1][b+1] = dp[a+1][b-1]
if p[b-1] == s[a] or p[b-1] == ".":
dp[a+1][b+1] = (dp[a+1][b] or dp[a][b+1] or dp[a+1][b-1])
return dp[-1][-1]

- 第二种:递归的方法。首先还是检验两个是否为空的情况, 这里如果
p为空的时候,判断s是否为空,从而知道返回True还是False。然后,判断匹配规则是否只有一个,如果为1,则判断匹配字符串长度是否为1,并且两者的第一个元素是否相同,或者说匹配规律为字符.,这里排除了规律为1的情况。之后开始重头戏递归,既然有两个及以上的匹配规律字符,那么已知这个*是代表前一个字符的,所以第一个字符不会是*,因此判断第二个字符是否为*。如果说第二个字符不是*,则如果要能够匹配,那么字符串和规则的第一个字符一定要能够匹配,也就是相同或者规则为.,如果匹配了,那么就进行递归,将前面已经匹配的第一个字符去掉,也就是用切片,将s[1:]和p[1:]重新回到函数中,同样的方法检验下一个字符。直到当前切片中的第二个元素不为*,也就是p[1] == "*",则进行下一步while循环,这里同样是要保证s非空,其次字符串和规则的首元素都要能够匹配,然后进行递归判断,判断s是否能匹配第三个元素及之后的规则,也就是p[2:],如果都能匹配,那么可以直接说明整体匹配成功,返回True。如果还不行,则把当前字符串的第一个字符用切片去掉,再继续判断,直到第一个字符和第一个规则不匹配了,退出循环,然后再去判断这之后的是否匹配。匹配就会直接返回True,不匹配就会返回False,然后递归结束。 - 这个方法比较基础,虽然说运行速度满了许多,但是这个思想需要掌握。
class Solution:
def isMatch(self, s: str, p: str) -> bool:
if not p:
return not s
if len(p) == 1:
return len(s) == 1 and (s[0] == p[0] or p[0] == ".")
if p[1] != "*":
if not s:
return False
return (s[0] == p[0] or p[0] == ".") and self.isMatch(s[1:], p[1:])
while s and (s[0] == p[0] or p[0] == "."):
if self.isMatch(s, p[2:]):
return True
s = s[1:]
return self.isMatch(s, p[2:])

- 第三种:用到
python的模块re来解决问题,这是python的一种解决正则表达式的模块。当我看到这个方法的时候,我觉得很神奇,但是相对技术含量就没有那么高了,所以这个方法比较适合学完前两种方法之后再看看了解。当然我对这个方法的也没有怎么看懂,主要是需要我们了解这个模块中的这个方法的作用。 - 参考学习资料:python正则表达式
import re
class Solution:
def isMatch(self, s: str, p: str) -> bool:
p = re.search(p, s)
if p and p.group() == s:
return True
else:
return False
# or
# return True if re.compile(p).fullmatch(s) else False

本文深入探讨了正则表达式匹配的三种方法:动态规划、递归和使用Python的re模块。首先介绍了动态规划的基本思路,通过构建二维DP数组实现高效匹配;随后讲解了递归方法,虽然效率较低但易于理解;最后提到了利用Python内置re模块快速解决问题的简便方式。

625

被折叠的 条评论
为什么被折叠?



