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
动态规划步奏:
1)确定边界的值
2)动态规划推导方程
http://blog.csdn.net/fzzying3/article/details/42057935
这里我们对该动态规划解法进行一定的分析说明,
这里我们采用b[i+1][j+1]代表s[0..i]匹配p[0..j]的结果,结果自然是采用布尔值True/False来表示。
1.因此,首先是对边界进行赋值,显然b[0][0] = true,两个空字符串的匹配结果自然为True
接下来,我们对b[i+1][0]进行赋值,显然对于空的匹配串,b[i+1][0]的数值必须为False
接着,我们对b[0][j+1]进行赋值,其值等于j > 0 && '*' == p[j] && b[0][j - 1],
1.首先是j>0,原因很简单,如果j=0则b[0][1]表示空的原串匹配长度为1的匹配串,无论长度为1的匹配串
为何种字符串,其结果都为false,试想一下,如果匹配串为一个字母字符自不必多说,如果为"."也容易理解,
如果为“*”,则是无效字符串,因为本题要求"*"之前必须要有一个字符,所以长度为1的字符串不可能为“*”;
2.其次'*' == p[j] && b[0][j - 1],如果一个空串和一个匹配串想要匹配成功,那么只有可能是:
p[0..j-2]匹配空串成功且无论p[j-1]是什么p[j]都必须是'*',所以就是'*' == p[j] && b[0][j - 1]
前两个边界赋值结束了之后,接下来就是经典的动态规划递推方程了:
1. 当前匹配串的字符不为’*‘,那么b[i + 1][j + 1] = b[i][j] && ('.' == p[j] || s[i] == p[j]),显然如果当前字符串不为'*',
则我们需要实打实地对s[i]和p[j]进行匹配,因此很自然s[0..i]和p[0..j]的匹配结果取决于s[0..i-1]和p[0..j-1]的
匹配结果与上s[i]和p[j]的匹配结果,因此就造就了上式;
2.若当前匹配串的字符为’*‘,那么b[i + 1][j + 1] = b[i + 1][j - 1] && j > 0 || b[i + 1][j]
|| b[i][j + 1] && j > 0 && ('.' == p[j - 1] || s[i] == p[j - 1]);
其意义为s[0..i]和p[0..j]的匹配结果取决于s[0..i]和p[0..j-2]的匹配结果,意味着我们忽略’*‘不重复,
其次s[0..i]和p[0..j]的匹配结果也可以取决于s[0..i]和p[0..j-1]的匹配结果,意味着我们利用'*'只重复一次,
再次s[0..i]和p[0..j]的匹配结果也可以取决于s[0..i-1]和p[0..j]以及s[i]和p[j-1]的匹配结果,这个是整个递推
表达式当中最难理解的部分,其含义是
如果s[0..i-1]和p[0..j]匹配了,说明当前的’*‘在一个字符之前的原串中已经得到匹配,那么要跟当前这个
字符匹配则只需要判断当前的s[i]和p[j-1]是否匹配即可,显然j必须要大于0,这里其实暗含了’*‘重复多次
的情形,试想s[0..i-1]都和p[0..j]匹配了,那么如果当时的匹配是不重复的匹配,那好,那么这次就是重复
一次的匹配,如果当时是重复n次的匹配,那么经过这次匹配就变成了重复n+1次的匹配了,那么可能有人
要问了既然第三项包含了重复一次的匹配,为何还需要第二项s[0..i]和p[0..j-1]匹配结果,原因是第三项建立
在s[0..i-1]和p[0..j]匹配的基础之上,完全有可能s[0..i-1]和p[0..j]不匹配,然而s[0..i]和p[0..j-1]匹配,应该这么说
’*‘重复一次的匹配有两种,一种是s[0..i-1]和p[0..j-2]匹配再加上当前s[i]和p[j-1]匹配或者s[0..i]和p[0..j-1]匹配。
简而言之:
状态转移方程如下:
dp[i][j] =
c1. p[j+1] != '*'时 if s[i] == p[j] dp[i][j] = dp[i+1][j+1]
else dp[i][j] = false
c2 p[j+1] == '*'时 (这个情况下,要扩展 *, dp[i][j] 从拓展的情况下,选择一个是真的结果)
if( s[i] == p[j] || p[j] == '.' && (*s) != 0) 当s[i] 和 p[j] 一样的时候,例如 aba, a*b这个时候,i = 0, j = 0, 自然可以匹配a a
如果p[j] == . 因为他可以匹配任何字符,所以和相等关系有基本一样的方式。
并且每一步匹配都要递增 i 的值,如果有成立的,则返回true,否则到匹配终了,返回通配符匹配完成后的结果。
bool isMatch(char* s, char* p) {
int i, j;
int m = strlen(s);
int n = strlen(p);
/**
* b[i + 1][j + 1]: if s[0..i] matches p[0..j]
* if p[j] != '*'
* b[i + 1][j + 1] = b[i][j] && s[i] == p[j]
* if p[j] == '*', denote p[j - 1] with x,
* then b[i + 1][j + 1] is true if any of the following is true
* 1) "x*" repeats 0 time and matches empty: b[i + 1][j -1]
* 2) "x*" repeats 1 time and matches x: b[i + 1][j]
* 3) "x*" repeats >= 2 times and matches "x*x": s[i] == x && b[i][j + 1]
* '.' matches any single character
*/
bool b[m + 1][n + 1];
b[0][0] = true;
for (i = 0; i < m; i++) {
b[i + 1][0] = false;
}
// p[0..j - 2, j - 1, j] matches empty if p[j] is '*' and p[0..j - 2] matches empty
for (j = 0; j < n; j++) {
b[0][j + 1] = j > 0 && '*' == p[j] && b[0][j - 1];
}
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
if (p[j] != '*') {
b[i + 1][j + 1] = b[i][j] && ('.' == p[j] || s[i] == p[j]);
} else {
b[i + 1][j + 1] = b[i + 1][j - 1] && j > 0 || b[i + 1][j] ||
b[i][j + 1] && j > 0 && ('.' == p[j - 1] || s[i] == p[j - 1]);
}
}
}
return b[m][n];
}
Regular Expression Matching——没理解的动态规划的更多相关文章
- leetcode problem 10 Regular Expression Matching(动态规划)
Implement regular expression matching with support for '.' and '*'. '.' Matches any single character ...
- Regular Expression Matching,regex,正则表达式匹配,利用动态规划
问题描述:Implement regular expression matching with support for '.' and '*'. '.' Matches any single char ...
- LeetCode10 Regular Expression Matching
题意: Implement regular expression matching with support for '.' and '*'. '.' Matches any single chara ...
- LeetCode (10): Regular Expression Matching [HARD]
https://leetcode.com/problems/regular-expression-matching/ [描述] Implement regular expression matchin ...
- 【leetcode】Regular Expression Matching (hard) ★
Implement regular expression matching with support for '.' and '*'. '.' Matches any single character ...
- 《LeetBook》leetcode题解(10): Regular Expression Matching——DP解决正则匹配
我现在在做一个叫<leetbook>的免费开源书项目,力求提供最易懂的中文思路,目前把解题思路都同步更新到gitbook上了,需要的同学可以去看看 书的地址:https://hk029.g ...
- regular expression matching DP
这个题目,我从前天晚上(8月6号晚上)调试到现在(8月8号16:21),太心酸了,不好好总结一下,就太对不起自己了! 这是题目: Implement regular expression matchi ...
- 66. Regular Expression Matching
Regular Expression Matching Implement regular expression matching with support for '.' and '*'. '.' ...
- 【JAVA、C++】LeetCode 010 Regular Expression Matching
Implement regular expression matching with support for '.' and '*'. '.' Matches any single character ...
随机推荐
- Java考试题
1. public class GC { 2. private Object o; 3. private voiddoSomethingElse(Object obj) { o ...
- 【bzoj2844】albus就是要第一个出场
Time Limit: 6 Sec Memory Limit: 128 MBSubmit: 2254 Solved: 934[Submit][Status][Discuss] Descriptio ...
- 省选模拟赛 LYK loves rabbits(rabbits)
题目描述 LYK喜欢兔子,它在家中养了3只兔子. 有一天,兔子不堪寂寞玩起了游戏,3只兔子排成一排,分别站在a,b,c这3个位置. 游戏的规则是这样的,重复以下步骤k次:选择两个不同的兔子A和B,假如 ...
- 浅谈cocosd之autorelease\retain\release的理解
三种情况,引出问题: 1) new出来的对象需要释放,而释放时,如果有其他人引用了这个对象,再次使用这个对象时,则会出现野指针情况. ==> 于是出现了引用计数的释放管理机制. 2) 对于一 ...
- Maven手动添加依赖的jar文件到本地Maven仓库
原文出处:https://www.iteblog.com/archives/646.html 寫得很好,轉走僅供學習,望諒解! Apache Maven,是一个软件(特别是Java软件)项目管理及自动 ...
- Atcoder #017 agc017 A.Biscuits 简单数学
LINK 题意:水题 求取数,使得和为奇数或偶数的方案数. 思路:统计奇数和偶数,组合求一下发现结果就是$2^{odd-1} + 2^{eve-1}$ 注意特殊情况,即奇数个为0又要求和为奇数的方案数 ...
- Python学习笔记(十八)@property
# 请利用@property给一个Screen对象加上width和height属性, # 以及一个只读属性resolution: # -*- coding: utf-8 -*- class Scree ...
- jQuery UI基本使用方法
其实jQuery UI早就在我的学习计划中,只不过因为计划安排始终处于待命状态,最近项目要用到jQuery UI,就提前学习一下,也想能够封装自己的UI库,这样就不用老按照别人的套路走了,像使用jQu ...
- GridControl GridView 修改表格中的标题居中
Grid Designer>Views>Appearance>HeaderPanel>TextOptions>HAIignment{Center} 依次打开并找到HAIL ...
- BestCoder Round #41 记。
大概整个过程都是很绝望的吧. 发现自己在七点之前是肯定搞不定网了..有冲动跑到机房去打 但是又不喜欢那样的气氛 这可是shi的场呢...好难过啊... 后来..好像是在和lyd讨论怎么把网络复原的过程 ...