刷题——正则表达式匹配

首先看题题目

给你一个字符串 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)

原文地址:https://www.cnblogs.com/fanwenkeer/p/11259461.html

时间: 2024-08-30 09:57:38

刷题——正则表达式匹配的相关文章

LeetCode第十题-正则表达式匹配

Regular Expression Matching 问题简介:给定字符串,给定匹配模式,判断字符串是否满足匹配模式 问题详解:一共有两种特殊模式: ‘.’ 匹配任何单个字符 ‘*’ 匹配前面元素的零个或多个 注:匹配的是整个给定字符串,不是部分 举例: 1: 输入: s = “aa” p = “a” 输出: false 解释: “a” 不匹配 “aa”. 2: 输入: s = “aa” p = “a*” 输出: true 解释: ‘*’ 代表 0 或多个字符 ‘a’ 3: 输入: s = “

leetcode刷题正则表达式

题目链接:https://leetcode-cn.com/problems/regular-expression-matching/ 这道题用到了动态规划: 关于动态规划请参考这篇博文:https://blog.csdn.net/u013309870/article/details/75193592 写的非常详细. 在做题过程中我参考了leetcode上某大佬的文章https://leetcode.com/problems/regular-expression-matching/discuss/

正则表达式匹配题

正则表达式匹配题 靶场地址:http://**.**.***.**:8010/re/?id=1. <?php $key='flag{********************************}'; $Regular=preg_match("/zkaq.*key.{2,9}:\/.*\/(key*key)/i", trim($_GET["id"]), $match); if( $Regular ){ die('key: '.$key); } 代码解释: p

剑指offer刷题记录

[TOC] 二维数组中的查找 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 解题思路:从右上角的元素进行判断,如果大于target说明这一列肯定都不是,所以将列数见一:如果小于target说明可能在下一行是等于target的,所以这一行都不是解,所以将行数加1.这样通过一个循环进行判断即可. class Solution { public: bool Find(int tar

LeetCode刷题总结-字符串篇

本文梳理对LeetCode上有关字符串习题的知识点,并给出对应的刷题建议.本文建议刷题的总数为32题.具体知识点如下图: 1.回文问题 题号:5. 最长回文子串,难度中等 题号:214. 最短回文串,难度困难 题号:564. 寻找最近的回文数,难度困难 2.子串问题(类似子集) 题号:76. 最小覆盖子串,难度困难 题号:115. 不同的子序列,难度困难 题号:522. 最长特殊序列 II,难度中等 题号:1163. 按字典序排在最后的子串,难度困难 3.表达式求值问题 题号:12. 整数转罗马

BZOJ 刷题记录 PART 4

[BZOJ1143]CTSC的题目...先用floyed传递闭包,然后直接上匈牙利算法. [BZOJ1452]从未写过的二维树状数组.好像很简单.. struct two_bit { int f[305][305]; inline void add(int x,int z,int A) { for (;x<=n;x+=L(x)) for (int y=z;y<=m;y+=L(y)) f[x][y]+=A; } inline int ask(int x,int z) { int ans=0; f

7、8月刷题总结

准备开学了囧,7.8月刷题记录,以后好来复习,并且还要好好总结! 数据结构: splay: [BZOJ]1503: [NOI2004]郁闷的出纳员(Splay) [BZOJ]1269: [AHOI2006]文本编辑器editor(Splay) [BZOJ]1507: [NOI2003]Editor(Splay) treap: [BZOJ]1862: [Zjoi2006]GameZ游戏排名系统 & 1056: [HAOI2008]排名系统(treap+非常小心) [BZOJ]3224: Tyvj

比较好的刷题网站推荐

1.Leetcode鼎鼎大名的Leetcode,据不完全统计在上面被刷过的题可以围绕地球三圈.(没说赤道哈,就是这么严谨.)总之,很多国内外的码农在上面刷题.难度从easy到hard都有,而且覆盖面极广.现在还增加了数据库和shell,相匹配的论坛也可以多看看.很锻炼和国外码农沟通的能力,对于以后去混Github也有好处. 特点:各种语言支持很广泛,题型覆盖很广,测试数据集较弱. 2.Codility同样一家著名的国外刷题网站.和Leetcode不同,它是专门帮各大软件公司笔试用的,只是副业提供

国内有哪些好的刷题网站?

http://www.zhihu.com/question/25574458 Luau Lawrence,Data Mining 弱鸡 / [email protected] 温梦强.石一帆.知乎用户 等人赞同 - Welcome To PKU JudgeOnline 北京大学的Online Judge.POJ上面的题目有点老了,但好处是做的人多,经典算法题多,解题报告也多,适合上手.- ZOJ :: Home 浙江大学的Online Judge.ZOJ用的不多,但为数不多的几次体验好像都还可以