刷题——正则表达式匹配
Posted fanwenkeer
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了刷题——正则表达式匹配相关的知识,希望对你有一定的参考价值。
首先看题题目
给你一个字符串 s
和一个字符规律 p
,请你来实现一个支持 ‘.‘
和 ‘*‘
的正则表达式匹配。
'.' 匹配任意单个字符
'*' 匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s
的,而不是部分字符串。
说明:
s
可能为空,且只包含从a-z
的小写字母。p
可能为空,且只包含从a-z
的小写字母,以及字符.
和*
。
示例 1:
输入:
s = "aa"
p = "a"
输出: false
解释: "a" 无法匹配 "aa" 整个字符串。
示例 2:
输入:
s = "aa"
p = "a*"
输出: true
解释: 因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。因此,字符串 "aa" 可被视为 'a' 重复了一次。
示例 3:
输入:
s = "ab"
p = ".*"
输出: true
解释: ".*" 表示可匹配零个或多个('*')任意字符('.')。
示例 4:
输入:
s = "aab"
p = "c*a*b"
输出: true
解释: 因为 '*' 表示零个或多个,这里 'c' 为 0 个, 'a' 被重复一次。因此可以匹配字符串 "aab"。
示例 5:
输入:
s = "mississippi"
p = "mis*is*p*."
输出: false
如果只是普通匹配,一个一个就好了,但是这题,有.
和*
需要考虑:
‘*‘ 代表可以匹配零个或多个前面的那一个元素
任意字符‘.‘
那就先暴力一下,嘻嘻嘻
首先,如果不考虑*
,那么问题就会非常简单,先把代码贴出来(因为考虑到一些坑点,先认为当s
和p
都为空是匹配的,当其中一个为空时不匹配,下面的代码有些冗余,不过只是一个样本,之后在此基础上再来考虑本题的*
)
初始版本来啦
(自己在Pythoncharm上面打的)
def ismatch(s, p):
m = len(s)
n = len(p)
if m == 0 and n == 0:
return "true"
if m == 0 or n == 0:
return "false"
if m != n:
return "false"
i = 0
while i < m:
if s[i] != p[i] and p[i] != '.' and s[i] != '.':
return "flase"
else:
i += 1
return "true"
def run():
s = input("输入s:")
p = input("输入p:")
print(ismatch(s,p))
run()
得到初始版本之后,将其转化成递归方法
def recuring_ismatch(s, p) -> bool:
if not p:
return not s
flag = bool(s) and p[0] in '.', s[0]
return flag and recuring_ismatch(s[1:], p[1:])
def run():
s = input("输入s:")
p = input("输入p:")
# print(ismatch(s,p))
flag = recuring_ismatch(s,p)
if flag == 0:
print("false")
else:
print("true")
run()
这样子看起来来就舒服很多了
接下来我们就要考虑到*
了
在进入递归之前我们就要考虑到下一个字符是不是*
,如果是的就有两种情况:
如果flag为1(能够匹配),那么s往后移1个。
如果flag为0(不能匹配,即为0次),那么p往后移动2个
核心代码
def recurng_ismatch(s, p) -> bool:
if not p:
return not s
flag = bool(s) and p[0] in '.', s[0]
if len(p) >= 2 and p[1] == '*':
return (flag and recuring_ismacth(s[1:], p)) or recuring_ismatch(s, p[2:])
else:
return recuring_ismatch(s[1:], p[1:])
有了递归的基础之后,在这之上继续做优化(动态规划),毕竟这个...
EMMM.......先通过了就好,接下来想想想怎么用动态规划啦(不要在意这些细节)
python有字典(dp[(i,j)]),相当于之前写的时候用到的二维数组,不过太久没有写忘得差不多了(其实本来也就没有学好。。。),看的网上的题解才写出来的,老了.......
创建demo字典用来存放
class Solution:
def isMatch(self, s: str, p: str) -> bool:
demo = dict()
def dp(i,j):
if (i,j) in demo:
return demo[(i,j)]
if j == len(p):
return i == len(s)
flag = i < len(s) and p[j] in '.', s[i]
if j+2 <= len(p) and p[j+1] == '*':
ans = (flag and dp(i+1,j)) or dp(i,j+2)
else:
ans = flag and dp(i+1,j+1)
demo[(i,j)] = ans
return ans
return dp(0,0)
s = ''
p = ''
sol = Solution()
flag = sol.isMatch(s, p)
if flag == 0:
print("false")
else:
print("true")
现在速度提升的就太快啦
不过对于动态规划的解法的确是很难掌握,需要多做一些题目才能掌握这种感觉,还得继续加油。
题解的连接在下方,有兴趣的可以去了解一下嗷
链接:https://leetcode-cn.com/problems/two-sum/solution/ji-yu-guan-fang-ti-jie-gen-xiang-xi-de-jiang-jie-b/
来源:力扣(LeetCode)
以上是关于刷题——正则表达式匹配的主要内容,如果未能解决你的问题,请参考以下文章