Regular Expression Matching & Wildcard Matching
2016-07-23 02:51
411 查看
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)
Example
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
分析:
如果我面试的时候没有复习到这道题,然后面试官又考了这道题,我一定会在给面试官感谢信里写两个字:fuck you! 这家伙明显是不想让我过的意思。 我花了不止一个小时来理解这题的意思。
1. '*' Matches zero or more of the preceding element.
意思不是说对于a*, 它只可以match a, aa, aaa, 无限多个a。它还可以match "" (空字符串)。卧槽,你想得到吗,你想得到吗,你真的想得到吗?你想不到吧!
2. ".*"意思是可以匹配任意字符串, 比如 “ddd”, "dda", "abc"。
3. 对于"a*b",它匹配“b”, 但是不匹配“a”.
4. 如果p开头为“*”,你得把它去除掉。
好了,如果你理解了上面部分,我们就可以用DP解决问题了。
我们首先创建一个二维数组来保存中间变量。
int m = p.length();
int n = s.length();
boolean[][] match = new boolean[m + 1][n + 1]; (p是横轴,s是纵轴)
match[i][j]表明对于p的前i - 1个字符,是否匹配s的前j - 1个字符。
这里分几种情况:
如果p.chartAt(i - 1) 是“.” 或者p.charAt(i - 1) == s.charAt(j - 1), 那么我们有:
match[i][j] = match[i - 1][j - 1];
如果p.chartAt(i - 1) 不是“.” 并且 p.charAt(i - 1) != s.charAt(j - 1), 那么我们有:
match[i][j] = false;
好了,关键点来了,如果p.chartAt(i - 1) == ‘*’,那么怎么办呢?
首先,如果p.charAt(i - 2) == '.' || p.charAt(i - 2) == s.charAt(j - 1)
那么我们是不是可以取match[i - 1][j - 1] (因为p.charAt(i - 1) == s.charAt(j - 1)如果上面条件成立), 或者 match[i - 2][j] ("x*" 直接变成 “”), 或者match[i][j - 1] ("x*" 变成 “x*x”) || match[i - 1][j] ("x*"变成 “x”);
所以,我们有: match[i][j] = match[i - 1][j - 1] || match[i - 2][j] || match[i][j - 1] || match[i - 1][j];
如果p.charAt(i - 2) != s.charAt(j - 1), 我们就只有一种方法:
match[i][j] = match[i - 2][j];
public class Solution { /** * @param s: A string * @param p: A string includes "." and "*" * @return: A boolean */ public boolean isMatch(String s, String p) { if (s == null || p == null) return false; while (p.length() >= 1 && p.charAt(0) == '*') { p = p.substring(1); } int m = p.length(); int n = s.length(); boolean[][] match = new boolean[m + 1][n + 1]; match[0][0] = true; for (int i = 1; i <= m; i++) { if (p.charAt(i - 1) == '*') { match[i][0] = match[i - 2][0]; } } for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { if (p.charAt(i - 1) == s.charAt(j - 1) || p.charAt(i - 1) == '.') { match[i][j] = match[i - 1][j - 1]; } else if (p.charAt(i - 1) == '*') { if (p.charAt(i - 2) == '.' || p.charAt(i - 2) == s.charAt(j - 1)) { match[i][j] = match[i - 1][j - 1] || match[i - 2][j] || match[i][j - 1] || match[i - 1][j]; } else { match[i][j] = match[i - 2][j]; } } else { match[i][j] = false; } } } return match[m] ; } }
Wildcard Matching
Implement wildcard pattern matching with support for'?'and
'*'.
'?'Matches any single character.
'*'Matches any sequence of characters (including the empty sequence).
The matching should cover the entire input string (not partial).
Have you met this question in a real interview?
Yes
Example
isMatch("aa","a") → false isMatch("aa","aa") → true isMatch("aaa","aa") → false isMatch("aa", "*") → true isMatch("aa", "a*") → true isMatch("ab", "?*") → true isMatch("aab", "c*a*b") → false 分析: 这题也是DP问题,横轴是S, 纵轴是P(含有?和*),那么我们可以得到:
if (p.charAt(i - 1) == s.charAt(j - 1) || p.charAt(i - 1) == '?') {
match[i][j] = match[i - 1][j - 1];
} else if (p.charAt(i - 1) == '*') {
match[i][j] = match[i - 1][j - 1] || match[i - 1][j] || match[i][j - 1];
// match[i][j - 1] 指的是用* 替换S中1个j或多个j之前的character,当然那些character可以是连续的。
}
public class Solution { /** * @param s: A string * @param p: A string includes "?" and "*" * @return: A boolean */ public boolean isMatch(String s, String p) { if (s == null || p == null) return false; boolean[][] match = new boolean[p.length() + 1][s.length() + 1]; match[0][0] = true; for (int i = 1; i < match[0].length; i++) { match[0][i] = false; } for (int i = 1; i < match.length; i++) { if (p.charAt(i - 1) == '*') { match[i][0] = match[i - 1][0]; } } for (int i = 1; i < match.length; i++) { for (int j = 1; j < match[0].length; j++) { if (p.charAt(i - 1) == s.charAt(j - 1) || p.charAt(i - 1) == '?') { match[i][j] = match[i - 1][j - 1]; } else if (p.charAt(i - 1) == '*') { match[i][j] = match[i - 1][j - 1] || match[i - 1][j] || match[i][j - 1]; } } } return match[p.length()][s.length()]; } }
相关文章推荐
- 给自己技术发展之路上的意见
- mybatis_SQL映射(2)
- 守护进程详细解读
- 大数计算
- 安装vs2013的entityframework
- 2016 Multi-University Training Contest 1 -1006 PowMod
- 串口通信的基本概念
- SparseArray解析
- php基础和http知识介绍
- 插件框架篇之Activity中theme、launchMode等设置问题
- if else
- UITableView的性能优化? 滑动的时候有种卡的感觉是为什么?怎么解决?
- 富文本
- python变量
- Android群英传之Android绘图机制与处理技巧
- Basic_Android关于buildToolVersion与CompileSdkVersion
- python变量
- LayoutInflater源码解析
- windows常用命令行总结
- 单行bash命令