刷题——正则表达式匹配

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

如果只是普通匹配,一个一个就好了,但是这题,有.*需要考虑:

‘*‘ 代表可以匹配零个或多个前面的那一个元素

任意字符‘.‘

那就先暴力一下,嘻嘻嘻

首先,如果不考虑*,那么问题就会非常简单,先把代码贴出来(因为考虑到一些坑点,先认为当sp都为空是匹配的,当其中一个为空时不匹配,下面的代码有些冗余,不过只是一个样本,之后在此基础上再来考虑本题的*

初始版本来啦

(自己在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)

以上是关于刷题——正则表达式匹配的主要内容,如果未能解决你的问题,请参考以下文章

Java正则表达式

java必刷题——正则表达式

leetcode刷题正则表达式

MySQL正则表达式匹配

正则表达式如何匹配空值?

正则表达式如何匹配空值?