10. 正则表达式匹配

题目

给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。

'.' 匹配任意单个字符 '*' 匹配零个或多个前面的那一个元素 所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。

说明:

s 可能为空,且只包含从 a-z 的小写字母。p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *。

题解

本题需要解决正则表达式匹配的问题,需要实现实现一个支持 '.' 和 '*' 的正则表达式匹配。我看了大多数题解直接就开始定义dp数组,让人不知道是怎么来。我觉得一个优秀的题解应该是侧重于思考方式的讲解以及解题经验的总结,而不只是答案的说明。那对于本题来说,我们是怎么思考的呢?

要明确一点,本题归根结底是一个字符串匹配的基本问题,只是需要实现其中的特殊情况, '.' 和 '*'。

问题一、普通的两个字符串如何匹配?

首先,对于字符串s与p,如何进行两个字符串匹配呢?

方法1 :迭代法

将两个字符串的每个对应元素一一对比,如果两个字符串长度相等,且整个过程每个字符都能对上则说明两个字符串匹配上了

if(s.length() != p.length()) return false;for(int i = 0,j = 0; i    if(s.charAt(i) != s.charAt(j)) return false;}return true;

上述的迭代过程i和j其实是一样的,可以使用一个i来表示,但是为了下文叙述方便,我这里特别的写了两个。

方法二:递归法

递归的一个非常重要的点就是:「不去管函数的内部细节是如何处理的,我们只看其函数作用以及输入与输出」。那现在来设计递归关系。

设计函数match:

  • 函数作用:判断两个字符字符串是否匹配
  • 输入:两个字符串s、p,字符串匹配的起始位置i、j
  • 输出:匹配成功输出true,匹配失败输出false;
public boolean match(String s, String p, int i, int j){    //如果两个字符串长度不相等,肯定不能匹配    if(s.length() != p.length()) return false;    //如果两个字符都是null,那么也是匹配的    if(s.equals("") && s.equals("")) return true;    //判断两个字符串的第一个字符是否相等    //如果相等,则比较后面的字符串    //如果不相等,直接返回false    boolean result = true;    if(i         if(s.charAt(i) == p.charAt(j)) match(s,p,i+1,j+1);        else result = false;    }        return result;}
问题二、向动态规划的过渡

如果能写成递归,基本就能改成动态规划,本题是能改成动态规划的,还是上面最基本的问题:两个字符串如何匹配?

因为是两个字符串,这里我们需要声明一个二维数组布尔数组

「表示字符串s中的前i个字符与字符串p中的前j个字符是否能够匹配」。如果能匹配则为true,反之为false;

假如我们已经算出了前i-1个字符与前j-1个字符的匹配情况了,那如何计算呢?

  • 如果,说明取决于
  • 如果,说明两个字符串不匹配
对于 '.' 和 '*'的处理

由于'.' 和 '*'都是在p中,所以

  • 当的时候,说明这个字符什么都可以当,和之前是一样的,故.

  • 当的时候这要分两种情况:

    如果*前面的字符能与s当前的字符匹配上的话,那就的状态就去取决于,也是就相当于看前面的状态。假如不能匹配的话,是不是就代表匹配失败了呢?不是的,因为这毕竟是一个 * 号而不是真正的要匹配的字符,「说白了大不了我不用他来匹配了,也就是使用0次」,那就的状态就去取决于。那这两种状态只要能满足其中一种就可以了,即:

接下来把上述过程翻译成代码即可。

代码

class Solution {    public boolean isMatch(String s, String p) {        int m = s.length();        int n = p.length();        boolean[][] dp = new boolean [m+1][n+1];        dp[0][0] = true;        for (int i = 0; i <= m; i++) {            for (int j = 1; j <= n; j++) {                if(p.charAt(j-1) != '*'){                    dp[i][j] = match(s,p,i,j) ? dp[i-1][j-1]:false;                }else{                    dp[i][j] = match(s,p,i,j-1) ? (dp[i][j-2] || dp[i-1][j]) : dp[i][j-2];                }            }        }        return dp[m][n];

    }    public boolean match(String s, String p, int i, int j){        if(i == 0) return false;        if(p.charAt(j-1) == '.') return true;        return s.charAt(i-1) == p.charAt(j-1);    }}

往期回顾

机器学习学习笔记------决策树机器学习学习笔记------LightGBMLeetCode刷题记录------两个正序数组的中位数

欢迎大家关注我的个人微信公众号:哦呦明知山有虎

正则匹配字符串无匹配不到_10. 正则表达式匹配相关推荐

  1. python匹配数字开头的内容_python使用正则表达式匹配字符串开头并打印示例

    python 正则表达式,怎样匹配以某个字符串开头,以str ="abcdefg123213qwe" 比如要匹配以abc开头,以qwe结尾,要怎样写呢?匹配以某个字符串开头,以某个 ...

  2. vim替换字符串带斜杠_Vim:正则表达式匹配一个字符串

    到目前为止,所有给出的答案对我来说都是错误的,因为它们执行的是贪婪匹配.在多次出现"否"的行中,它们将匹配最后一个: YES YES YES YES no YES YES no Y ...

  3. 正则匹配字符串无匹配不到_实现简单正则表达式匹配

    这是facebook的面试题 实现包含以下特殊字符的正则表达匹配 "." 匹配任意一个字符 "*" 匹配任意多个前面的字符 例如给定正则表达"ra.& ...

  4. linux匹配字符串型号,Linux shell脚本:如何匹配子字符串和正则表达式

    如何获得所有具有"client_type = 0"的"clid's"?管道字符"|"分离每个客户的信息.文本,我有仅仅是一个行:Linux ...

  5. python 匹配字符串多个_在Python中匹配多个数据集的字符串

    这里有一小段你可以启发的代码.主要思想是使用递归函数. 为简单起见,我承认我已经在列表中加载了数据,但是你可以在之前从文件中获取它们: data_files = [ 'data_a.dat', 'da ...

  6. 匹配字符串-好技能-正则表达式

    1. 正则表达式规则 1.1 普通字符 字母.数字.汉字.下划线.以及后边章节中没有特殊定义的标点符号,都是"普通字符".表达式中的普通字符,在匹配一个字符串的时候,匹配与之相同的 ...

  7. 匹配字符串-正则表达式

    原文地址:http://www.cnblogs.com/zhujiabin/p/5669006.html 1. 正则表达式规则 1.1 普通字符 字母.数字.汉字.下划线.以及后边章节中没有特殊定义的 ...

  8. python re正则提取ip地址_python 正则表达式匹配IP地址

    一.实验环境 1.Windows7x64_SP1 2.anaconda2.5.0 + python2.7(anaconda集成,不需单独安装) 3.pyinstaller3.0 二.实验目的 从tex ...

  9. php匹配图片,PHP正则匹配img及标签各属性值(匹配图片函数)

    有一个项目要获取页面中所有img标签中的图片地址,这里我们使用到了preg_match_all正则函数,然后看我下面的一些参数即可实现了. 例 代码如下 复制代码 $ext = 'jpg|jpeg|g ...

  10. linux下匹配字符串,linux上强大的字符串匹配工具详解-grep

    1. grep 是什么 grep 是用于匹配输入数据中符合条件的字符串的工具,其匹配过程支持正则表达式,因而匹配能力非常强大. grep 可以从文件或者标准输入设备中读取数据,若不指定任何文件名称,或 ...

最新文章

  1. 解决360浏览器兼容模式的页面显示问题
  2. java和python的web自动化有什么区别-三分钟看懂Python和Java的区别
  3. Oracle10g安装步骤(一)
  4. boost::array用法的测试程序
  5. java servlet 部署到tomcat_如何把spring boot项目部署到tomcat容器中
  6. 网站加载速度 优化_您肯定要优化网站的加载速度。 这是如何做。
  7. 20179209《Linux内核原理与分析》第一周作业
  8. html5 datepicker使用方法,WdatePicker.js时间日期插件的使用方法
  9. java 获取子文件夹_JAVA之File类 获取一个目录下的所有文件夹和文件,包括子文件夹和子文件...
  10. 使用springMVC提供的CommonsMultipartResolver文件解析器,实现文件轻松上传
  11. 状态模式(Strategy Pattern)
  12. dns服务器迁移方法简单说明
  13. 文本比较/文本对比在线工具
  14. 定时计数程序c语言,MCS-51系列单片机C语言编程定时/计数器程序模板
  15. 微信小程序android和IOS拨打电话区别
  16. 关于物联网进入元宇宙时代的基础与发展思考
  17. 微信小程序服务器和app互通,解读:App 与小程序的互通能力和限制
  18. 国二c语言是人工改卷还是机器改卷,雅思机考作文是机器批卷吗,雅思机考,阅读和听力是机器判卷,还是人工判卷?...
  19. 【牛客网-公司真题-前端入门篇】——58同城2021校招笔试-前端
  20. 迪杰斯特拉(Dijkstra)算法之两点之间的最短距离问题

热门文章

  1. H264 SPS分析
  2. ARM汇编,MCR和MRC
  3. VC对密码加密和解密函数
  4. 比较x^y和y^x的大小
  5. 最短路之floy算法
  6. python怎么用numpy_Python:一篇文章掌握Numpy的基本用法
  7. php7.1 win7,win7 配置AMP环境(apache2.4.39 + php7.1.28)
  8. 微信读书vscode插件_众所周知,拥有了vscode就拥有了一切
  9. 在c语言中保留35位小数,C语言程序设计复习题(供学有余力学生练习)(35页)-原创力文档...
  10. 图:[营养美食知识竞赛-PPT双屏技术策划]浙江海洋学院营养美食知识竞赛结束.