10. Regular Expression Matching
Implement regular expression matching with support for '.' and '*'.
'.' Matches any single character.
'*' Matches zero or more of the preceding element. The matching should cover the entire input string (not partial). The function prototype should be:
bool isMatch(const char *s, const char *p) Some examples:
isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "a*") → true
isMatch("aa", ".*") → true
isMatch("ab", ".*") → true
isMatch("aab", "c*a*b") → true
回溯算法 Backtracking
当匹配‘b*’,我们会略过s中的所有字符'b';之后所有的'b'就无法再被'bb'匹配,使用 贪心算法,这个匹配的返回值将会是false,但我们预计的是 true。
有些人可能会对此提出改进,在s中,计算连续的字符 'b' 的个数,如果个数比在p中‘b*’后的连续b个数小或相等,那么我们认为匹配。
这里,p中的“.*” 意味着‘.’ 重复0 or 随意次。因为 ‘.’ 可以匹配任意字符,所以无法确定 ‘.’ 到底应该重复多少次。p中的 ‘c’ 到底去匹配第一个,还是第二个'c' ,不得而知。
所以我们需要使用 回溯backtracking 当匹配失败的时候。 我们返回到上一次匹配成功的状态,并用‘*‘ 匹配更多的s中的字符。 该算法需要使用到 递归recursion。
- 如果p中的下一个字符不是 ‘*’, 则它必须匹配当前s中的字符。并继续用下一个字符,去匹配s中的字符。
- 如果p中的下一个字符是 ‘*’, 那我们必须使用 暴力搜索brute force 去匹配s中的当前字符,不断重复,直到不再匹配
代码
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
class Solution {public: bool isMatch(string s, string p) { if (p.size() == 0) return s.size() == 0;//一定不能写反 if (p[1] != '*') return (s[0] == p[0] || p[0] == '.' && !s.empty()) && isMatch(s.substr(1), p.substr(1)); int i = 0; while (s[i] == p[0] || (p[0] == '.' && i < s.size())) { if (isMatch(s.substr(i), p.substr(2))) return true; ++i; } return isMatch(s.substr(i), p.substr(2)); }}; |
现实应用中,实际上是使用 正则表达式 grep tool 工具来匹配字符的。
动态规划 Dynamic Programming
首先说明一下规则,dp[m][n] 数组返回值boolean.。它告诉我们长度n的正则表达式,是否匹配长度m的字符串。
dp[m][n]: if s[0..m-1] matches p[0..n-1]
dp[m][0] 当 m > 0, 永远false。空的正则表达式不会匹配任何字符串。
dp[0][n] 可以是 true 或 false。如果p[j - 1] 是'*' 并且p[0..j - 3] 匹配空字符串,那么p[0.., j - 3, j - 2, j - 1] 也匹配空字符串s,
|
1
2
3
4
5
6
|
dp[0][0] = true;for (int i = 1; i <= m; i++) dp[i][0] = false;// p[0.., j - 3, j - 2, j - 1] matches empty if p[j - 1] is '*' and p[0..j - 3] matches emptyfor (int j = 1; j <= n; j++) dp[0][j] = j > 1 && '*' == p[j - 1] && dp[0][j - 2]; |
* dp[i][j]: if s[0..i-1] matches p[0..j-1]* if p[j - 1] != '*'* dp[i][j] = dp[i - 1][j - 1] && s[i - 1] == p[j - 1]* if p[j - 1] == '*', denote p[j - 2] with x* dp[i][j] is true if any of the following is true* 1) "x*" repeats 0 time and matches empty: dp[i][j - 2]* 2) "x*" repeats >= 1 times and matches "x*x": s[i - 1] == x && dp[i - 1][j]* '.' matches any single character
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
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 = 1; i <= m; ++i) dp[i][0] = false; for (int j = 1; j <= n; ++j) dp[0][j] = j > 1 && p[j - 1] == '*' && dp[0][j - 2]; for (int i = 1; i <= m; ++i) for (int j = 1; j <= n; ++j) { if (p[j - 1] != '*') dp[i][j] = dp[i - 1][j - 1] && (s[i - 1] == p[j - 1] || p[j-1] == '.'); else dp[i][j] = dp[i][j - 2] //如果* 代表不重复,即空字符 || dp[i - 1][j] && (s[i - 1] == p[j - 2] || '.' == p[j - 2]);//* 代表重复>=1次 } return dp[m][n]; }}; |
10. Regular Expression Matching的更多相关文章
- leetcode 10 Regular Expression Matching(简单正则表达式匹配)
最近代码写的少了,而leetcode一直想做一个python,c/c++解题报告的专题,c/c++一直是我非常喜欢的,c语言编程练习的重要性体现在linux内核编程以及一些大公司算法上机的要求,pyt ...
- leetcode 10. Regular Expression Matching 、44. Wildcard Matching
10. Regular Expression Matching https://www.cnblogs.com/grandyang/p/4461713.html class Solution { pu ...
- Leetcode 10. Regular Expression Matching(递归,dp)
10. Regular Expression Matching Hard Given an input string (s) and a pattern (p), implement regular ...
- 刷题10. Regular Expression Matching
一.题目说明 这个题目是10. Regular Expression Matching,乍一看不是很难. 但我实现提交后,总是报错.不得已查看了答案. 二.我的做法 我的实现,最大的问题在于对.*的处 ...
- leetcode problem 10 Regular Expression Matching(动态规划)
Implement regular expression matching with support for '.' and '*'. '.' Matches any single character ...
- [LeetCode] 10. Regular Expression Matching 正则表达式匹配
Given an input string (s) and a pattern (p), implement regular expression matching with support for ...
- [LeetCode] 10. Regular Expression Matching
Implement regular expression matching with support for '.' and '*'. DP: public class Solution { publ ...
- 【leetcode】10.Regular Expression Matching
题目描述: Implement regular expression matching with support for '.' and '*'. '.' Matches any single cha ...
- Java [leetcode 10] Regular Expression Matching
问题描述: Implement regular expression matching with support for '.' and '*'. '.' Matches any single cha ...
随机推荐
- linux学习心态建设
为啥我们要学习Linux 技术的价值不在于这个技术有多么高超,而在于技术本身给我们带来什么价值,所以很多时候我们学习一个技术,不能盲目学,是为了使用这个技术,知道这个技术的使用场景,知道这个技术带来的 ...
- markdown 自定义一个锚点
//自定义锚点 s "m[": function mlink( text ) { var orig = String(text); // Inline content is pos ...
- 疯狂java讲义--笔记
第一章.Java语言概述与开发环境 什么是软件:一系列按照特定顺序组织的计算机数据和指令的集合: 交互方式:两种 GUI(Graphical User Interface) 图像界面 .CLI (Co ...
- 在iOS9中 xcode7 网络请求 如图片请求不显示等
Application Transport Security has blocked a cleartext HTTP (http://) resource load since it is inse ...
- Eclipse 打开当前文件所在的文件夹
两种方法: 1.安装EasyExplorer插件,有了这个插件就可以很方便地打开资源文件所在的文件夹了. EasyExplorer 从 http://sourceforge.net/projects/ ...
- iOS7之后的文本高度封装
#import "NSString+Util.h" @implementation NSString (Util) +(CGFloat)changeStationWidth:(NS ...
- OpenCV FileStorage 使用记录
FileStorage OpenCV 中的 FileStorage 类能够读写硬盘中的.xml和.yaml文件,这里我们只讨论对 .xml 的以下几种操作: 写入(FileStorage::WRITE ...
- 第三天 函数 三元运算 lambda表达式 内置函数 文件操作
面向过程: 直接一行一行写代码,遇到重复的内容复制黏贴. 不利于代码阅读 代码没有复用 面向对象 将代码块定义为函数,以后直接调用函数 增强了复用性 函数的定义方法 def 函数名(传递参数): 函数 ...
- MVC修改文件上传大小问题
在web.config文件的system.web节点的httpRuntime节点加入 maxRequestLength="2147483647" executionTimeout= ...
- 淘淘商城_day01_课堂笔记
今日大纲 聊聊电商行业 电商行业发展 11.11 2015双11: 2016年: 预测:2017年的双11交易额将达到:1400亿 电商行业技术特点 淘淘商城简介 淘淘商城的前身 电商行业的概念 B2 ...