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 {
public boolean isMatch(String s, String p) {
if (s == null || p == null) return false; while (p.length() >= && p.charAt() == '*') {
p = p.substring();
}
int row = p.length(), col = s.length();
boolean[][] match = new boolean[row + ][col + ];
match[][] = true;
for (int i = ; i <= row; i++) {
if (p.charAt(i - ) == '*') {
match[i][] = match[i - ][];
}
} for (int i = ; i <= row; i++) {
for (int j = ; j <= col; j++) {
if (p.charAt(i - ) == s.charAt(j - ) || p.charAt(i - ) == '.') {
match[i][j] = match[i - ][j - ];
} else if (p.charAt(i - ) == '*') {
if (p.charAt(i - ) == '.' || p.charAt(i - ) == s.charAt(j - )) {
match[i][j] = match[i - ][j - ] || match[i - ][j] || match[i][j - ] || match[i - ][j];
} else {
match[i][j] = match[i - ][j];
}
} else {
match[i][j] = false;
}
}
}
return match[row][col];
}
}

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 {
public boolean isMatch(String s, String p) {
if (s == null || p == null) return false;
boolean[][] match = new boolean[p.length() + ][s.length() + ];
match[][] = true;
for (int i = ; i < match.length; i++) {
if (p.charAt(i - ) == '*') {
match[i][] = match[i - ][];
}
} for (int i = ; i < match.length; i++) {
for (int j = ; j < match[].length; j++) {
if (p.charAt(i - ) == s.charAt(j - ) || p.charAt(i - ) == '?') {
match[i][j] = match[i - ][j - ];
} else if (p.charAt(i - ) == '*') {
match[i][j] = match[i - ][j - ] || match[i - ][j] || match[i][j - ];
}
}
} return match[p.length()][s.length()];
}
}

Regular Expression Matching & Wildcard Matching的更多相关文章

  1. leetcode 10. Regular Expression Matching 、44. Wildcard Matching

    10. Regular Expression Matching https://www.cnblogs.com/grandyang/p/4461713.html class Solution { pu ...

  2. [LeetCode] Regular Expression Matching 正则表达式匹配

    Implement regular expression matching with support for '.' and '*'. '.' Matches any single character ...

  3. 【leetcode】Regular Expression Matching (hard) ★

    Implement regular expression matching with support for '.' and '*'. '.' Matches any single character ...

  4. 10. Regular Expression Matching字符串.*匹配

    [抄题]: Given an input string (s) and a pattern (p), implement regular expression matching with suppor ...

  5. leetcode 10 Regular Expression Matching(简单正则表达式匹配)

    最近代码写的少了,而leetcode一直想做一个python,c/c++解题报告的专题,c/c++一直是我非常喜欢的,c语言编程练习的重要性体现在linux内核编程以及一些大公司算法上机的要求,pyt ...

  6. [LeetCode] 10. Regular Expression Matching 正则表达式匹配

    Given an input string (s) and a pattern (p), implement regular expression matching with support for  ...

  7. [LeetCode] 10. Regular Expression Matching

    Implement regular expression matching with support for '.' and '*'. DP: public class Solution { publ ...

  8. No.010:Regular Expression Matching

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

  9. Regular Expression Matching

    Implement regular expression matching with support for '.' and '*'. '.' Matches any single character ...

随机推荐

  1. 从零开始学Kotlin-数据类型(2)

    从零开始学Kotlin基础篇系列文章 基本数据类型 Kotlin 的基本数值类型包括 Byte.Short.Int.Long.Float.Double 等: 数据-------位宽度 Double-- ...

  2. Windows 设置开机自动登录

    1. 自己一些windows的虚拟机 有时候开机之后 输入用户名密码时间特别长. 需要等待很久, 如果能够设置开机自动登录的话 能够节约很多时间. 2. 最简单的办法  运行输入 control us ...

  3. Alpha、伪Beta 发布后,严一格的个人感想与体会

    伪Beta发布在4月15日下午2.30左右结束,严一格所在的“爆打”团队产品发布成功.下面是我的想法和体会~ 1.作为“爆打”团队中的一员,我对我们团队可以成功发布Alpha版本和伪Beta版本感到由 ...

  4. BZOJ2729 HNOI2012排队(组合数学+高精度)

    组合入门题.高精度入门题. #include<iostream> #include<cstdio> #include<cstdlib> #include<cs ...

  5. 2017-2018 ACM-ICPC, Asia Daejeon Regional Contest F(递推)

    F题 Problem F Philosopher’s Walk 题意:给你n,m,n代表一个长宽都为2的n次方的格子里,m代表走了从左下角开始走了m米,求最后的坐标. 思路: 看上图很容易便可以看出规 ...

  6. Javascript实现倒计时和根据某时间开始计算时间

    JavaScript 代码 <script type="text/javascript"> var time_start = new Date('2018','7',' ...

  7. 前端学习 -- Css -- 字体分类

    在网页中将字体分成5大类: serif(衬线字体) sans-serif(非衬线字体) monospace (等宽字体) cursive (草书字体) fantasy (虚幻字体) 可以将字体设置为这 ...

  8. Linux上查看文件大小的用法(转载)

    具体用法可以参考:https://blog.csdn.net/linfanhehe/article/details/78560887 当磁盘大小超过标准时会有报警提示,这时如果掌握df和du命令是非常 ...

  9. Ajax跨域CORS

    在Ajax2.0中多了CORS允许我们跨域,但是其中有着几种的限制:Origin.Methods.Headers.Credentials 1.Origin 当浏览器用Ajax跨域请求的时候,会带上一个 ...

  10. es6 export 和 export default区别

    相信很多人都使用过export.export default.import,然而它们到底有什么区别呢? 在JavaScript ES6中,export与export default均可用于导出常量.函 ...