LeetCode 10. Regular Expression Matching

本博客参考:http://www.cnblogs.com/grandyang/p/4461713.html
详细解析见另一题:【重点】剑指offer——面试题53:正则表达式匹配里面的代码风格是C的,现在把它改成C++风格的代码。在剑指offer53题的代码中,由于代码风格的原因,未考虑p.size() == 1的情况,这里也做了适当修改

Solution1:递归

代码中的注释写的不是太清楚,加一点:
一、当模式中的第二个字符不是“*”时:
1、如果字符串第一个字符和模式中的第一个字符相匹配,那么字符串和模式都后移一个字符,然后匹配剩余的。
2、如果字符串第一个字符和模式中的第一个字符相不匹配,直接返回false。
二、当模式中的第二个字符是“*”时:
如果字符串第一个字符跟模式第一个字符不匹配,则模式后移2个字符,继续匹配。如果字符串第一个字符跟模式第一个字符匹配,可以有3种匹配方式:
1、x*匹配0个字符。模式后移2字符,相当于x*被忽略;(一开始忘了即使当前字符匹配,也存在忽略掉的情况!!!)
2、x*匹配1个字符。字符串后移1字符,模式后移2字符;
3、x*匹配多于1个字符。字符串后移1字符,模式不变,即继续匹配字符下一位,因为*可以匹配多位;
注意:情况2可以被情况1和情况3包含。执行一次情况3,再执行一次情况1,就相当于情况2。

class Solution {public:bool isMatch(string s, string p) {if (p.empty()) return s.empty();if (p.size() == 1) {return (s.size() == 1 && (s[0] == p[0] || p[0] == '.'));}//if the next character in pattern is not '*'if (p[1] != '*') {//第一个条件没有判断s.size()是否为0,看似有溢出的可能//实际上此处另有玄妙,见下面分解!if (s[0] == p[0] || (!s.empty() && p[0] == '.'))return isMatch(s.substr(1), p.substr(1));elsereturn false;}//if the next character is '*'else {if (s[0] == p[0] || (!s.empty() && p[0] == '.'))return isMatch(s, p.substr(2)) || isMatch(s.substr(1), p);//刚开始一直不懂为何要返回match(str, pattern+2)的值,原因在于'*'可以匹配0个字符//即使是当前字符匹配,也存在匹配0个字符的情况elsereturn isMatch(s, p.substr(2));}}
};

关于C++中空string

C++中的string和C语言的字符串有一点很像,那就是当string对象其实也是以字符’\0’结尾的,这跟C语言中一致。
这也就解释了下面这段程序不会报错的原因。

string s = ""; // s是空串
cout << (int)s[0] << endl;
//程序输出为0,也就是'\0'字符

Solution2:动态规划

动态规划还是稍微有点难理解啊,不过至少要牢记递归的方法!
我们也可以用DP来解,定义一个二维的DP数组,其中dp[i][j]表示s[0,i)和p[0,j)是否match,然后有下面三种情况(下面部分摘自这个帖子):
1. P[i][j] = P[i - 1][j - 1], if p[j - 1] != ‘*’ && (s[i - 1] == p[j - 1] || p[j - 1] == ‘.’);
2. P[i][j] = P[i][j - 2], if p[j - 1] == ‘*’ and the pattern repeats for 0 times;
3. P[i][j] = P[i - 1][j] && (s[i - 1] == p[j - 2] || p[j - 2] == ‘.’), if p[j - 1] == ‘*’ and the pattern repeats for at least 1 times.

class Solution {
public:bool isMatch(string s, string p) {int m = s.size(), n = p.size();vector<vector<bool>> dp(m + 1, vector<bool>(n + 1, false));dp[0][0] = true;for (int i = 0; i <= m; ++i) {for (int j = 1; j <= n; ++j) {if (j > 1 && p[j - 1] == '*') {dp[i][j] = dp[i][j - 2] || (i > 0 && (s[i - 1] == p[j - 2] || p[j - 2] == '.') && dp[i - 1][j]);} else {dp[i][j] = i > 0 && dp[i - 1][j - 1] && (s[i - 1] == p[j - 1] || p[j - 1] == '.');}}}return dp[m][n];}
};

【重点 递归 动态规划 正则表达式匹配】LeetCode 10. Regular Expression Matching相关推荐

  1. LeetCode 10. Regular Expression Matching / 44. Wildcard Matching

    10. Regular Expression Matching 经典DP题目,比较复杂,需要多复习. dp[i][j] 表示 s 下标0~i,p 下标0~j 是否能够匹配   dp[i-1][j-1] ...

  2. leetcode 10 Regular Expression Matching

    题目连接 https://leetcode.com/problems/regular-expression-matching/ Regular Expression Matching Descript ...

  3. 【To Understand! 重点 递归 动态规划 正则表达式匹配】LeetCode 44. Wildcard Matching

    LeetCode 44. Wildcard Matching Solution1:我的答案 递归,时间复杂度是O(2n)O(2n)O(2^n)因为超时未能AC 只是记录一下,以警示后人-- class ...

  4. LeetCode 10. Regular Expression Matching python特性、动态规划、递归

    前言 本文主要提供三种不同的解法,分别是利用python的特性.动态规划.递归方法解决这个问题 使用python正则属性 import reclass Solution2:# @return a bo ...

  5. LeetCode 10 Regular Expression Matching(字符串匹配)

    题目链接 https://leetcode.com/problems/regular-expression-matching/?tab=Description   '.' Matches any si ...

  6. LeetCode:10. Regular Expression Matching

    老大难问题,终于算是理解了. 首先状态定义不难写(哈哈): dp[i][j]: s[0->i-1] p[0->j-1],它们是不是符合. 难的是状态转移方程(又一次验证): 1.如果s[i ...

  7. 【LeetCode】10. Regular Expression Matching

    题目: Implement regular expression matching with support for '.' and '*'. '.' Matches any single chara ...

  8. Leetcode Q10: Regular Expression Matching

    题目10: (该题目拿到手没什么特别好的思路,从网上看的别人的解法,然后写了下自己的理解,需要常回顾) Implement regular expression matching with suppo ...

  9. 【算法】Regular Expression Matching 正则匹配

    [算法]Regular Expression Matching 正则匹配 题目 解题思路 代码实现 题目 Given an input string ( s ) and a pattern ( p ) ...

最新文章

  1. ES6的这些操作技巧,你会吗?
  2. python第四十九天--paramiko模块安装大作战
  3. java集合——具体的集合
  4. Knative 核心概念介绍:Build、Serving 和 Eventing 三大核心组件
  5. python调试和测试有什么区别和联系_软件测试和测试开发到底有什么区别跟联系?...
  6. ECCV2018--点云匹配
  7. 日期和毫秒值 例子
  8. java 代码压缩javascript_利用Java来压缩 JavaScript 代码详解
  9. 一段实现分页的存储过程
  10. Atitit 获取mp3音乐文件的音乐名与歌手结构化元数据 nlp java 目录 1.1. 一、MP3文件的元数据 1 1.2. MP3文件的数据结构以及为mp3内嵌歌词的代码 3 1.3.
  11. 华为三层交换机-路由-硬件防火墙的配置
  12. [含论文+源码等]javaweb银行柜员业务绩效考核系统
  13. 操作系统课程设计(页面置换算法 C语言)
  14. [963]Android app代理软件
  15. 2022最新Postman安装以及基本操作使用教程
  16. 如何缩小jpg图片大小?jpg格式怎么压缩?
  17. PTA - 数据库合集3
  18. 2021年 个人年度总结
  19. Post Office
  20. sql查询将一对多转化为一对一

热门文章

  1. BLOG 可能的 BUG
  2. C++----为什么不让用using namespace std
  3. 【C++笔记】构造函数与析构函数相关知识
  4. python 百度识图_python如何调用百度识图api
  5. android和emui的版本对应,同为Android 操作系统的小米MIUI和华为EMUI, 谁更优秀?
  6. 多媒体实时交互系统主要由系统服务器,多媒体设备和多媒体交互系统专利_专利申请于2017-03-08_专利查询 - 天眼查...
  7. python编写脚本教程_python编写一个会算账的脚本的示例代码
  8. vue设置页面滚动高度_vue中获取滚动高度或指定滚动到某位置
  9. java 记录考勤记录_Java中的记录器– Java记录示例
  10. router 53 亚马逊_亚马逊53号公路