LeetCode(10)RegularExpresssionMatching

原创 2013年12月06日 07:19:34

我觉这道题目得挺难的,想了很久也没想清楚%>_<%于是看了解题报告

题目解释

'.' 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

给定的例子中,有一个比较难懂,是这样的。
isMatch("ab", ".*") → true
这个式子的判定结果是true。理由是.*理解为重复任意字符任意次.......而a是任意字符,b也是任意字符。所以ture


基本思路:
比较困难的问题在这里。看下面两个例子的比较:
例1: isMatch("aaaaab","a*b"),
为了表达方便记录为    isMatch("a1a2a3a4a5b1","a6*b2"),
显然a6应该匹配a1a2a3a4a5,然后b2匹配b1。

例2: isMatch("aaaaab","a*ab"),
为了表达方便记录为    isMatch("a1a2a3a4a5b1","a6*a7b2"),
显然a6应该匹配a1a2a3a4,然后a7匹配a5,然后b2匹配b1。
于是发现,当正则表达式中有*的时候,比较讨厌,你不知道到底要在s中匹配多长。
这个问题的结构说明这个问题天生适合用递归来解决。就像leetcode的解答报告中说的If you are stuck, recursion is your friend.
这个问题的结构还说明*很特殊所以需要特殊对待,于是基本思路是
把p分隔为若干个小单位,要么是一个字符构成的小单位,要么是一个字符和后面一个'*'构成的小单位。
逐一检查这样的小单位是否能够和s匹配。这其中,到底这样的小单位匹配多长的s是需要我们逐一检查的,也就是需要我们暴力一下的。

抄袭代码:

//
//  Solution.h
//  LeetCodeOJ_010_RegMatching
//
//  Created by feliciafay on 12/4/13.
//  Copyright (c) 2013 feliciafay. All rights reserved.
//

#ifndef LeetCodeOJ_010_RegMatching_Solution_h
#define LeetCodeOJ_010_RegMatching_Solution_h
#include <iostream>
#include <string>
#include <assert.h>
// Input:	"bbbba", ".*a*a"
class Solution {
public:
    bool isMatch(const char *s, const char *p) {
        assert(s && p);
        if (*p == '\0') return *s == '\0';
        
        // next char is not '*': must match current character
        if (*(p+1) != '*') {
            assert(*p != '*');
            return ((*p == *s) || (*p == '.' && *s != '\0')) && isMatch(s+1, p+1);
        }
        // next char is '*'
        while ((*p == *s) || (*p == '.' && *s != '\0')) {
            if (isMatch(s, p+2))
                return true;
            s++;
        }
        //继续匹配剩下的部分
        return isMatch(s, p+2);
        }
};
#endif

小结
(1)欣赏一下这句的简洁和巧妙 
return ((*p == *s) || (*p == '.' && *s != '\0')) && isMatch(s+1, p+1);
(2)
注意这里是
    if (isMatch(s, p+2)) return true;
而不是
    return  (isMatch(s, p+2));
因为逻辑是,在若干次暴力搜索中,只要又一次匹配就返回true,不管之前失败了几次。
(3)
之前个人错误地认为逻辑其实应该是
//错误写法
s++;
if (isMatch(s, p+2)) return true;
但是实际正确写法却是

if (isMatch(s, p+2)) return true;
s++;
为什么呢?

看这样一个例子就能理解了。 isMatch(“a”, "a*a"),这里"a"和"a*a"显然应该是匹配的。为了方便,表达为
原串: a1
正则: a2*a3
如果按照错误写法,那么a1匹配a2之后,将检查a3和'\0'发现不匹配于是返回结果为不匹配。
可是实际上,a2*表达的意思是把a2重复0次或者多次,错误的写法没有考虑到把a2重复0次的情况。
按照正确的写法,就可以考虑到a2重复0次的情况,从而判断a1是否匹配a3,从将最终结果返回为匹配。
所以正确的写法是

if (isMatch(s, p+2)) return true;
s++;
(4) LeetCode对思路讲解的的原话

We need some kind of backtracking mechanism such that when a matching fails, we return to the last successful matching state and attempt to match more characters in s with ‘*’. This approach leads naturally to recursion.

If the next character of p is NOT ‘*’, then it must match the current character of s. Continue pattern matching with the next character of both s and p.
If the next character of p is ‘*’, then we do a brute force exhaustive matching of 0, 1, or more repeats of current character of p… Until we could not match any more characters.

LeetCode 10. Regular Expression Matching(正则表达式匹配)

原题网址:https://leetcode.com/problems/regular-expression-matching/ Implement regular expression match...
  • jmspan
  • jmspan
  • 2016年05月19日 05:10
  • 972

leetcode第10题——***Regular Expression Matching

题目 Implement regular expression matching with support for '.' and '*'. '.' Matches any single char...
  • buptlrw
  • buptlrw
  • 2016年01月05日 16:07
  • 1283

(java)leetcode-10

其实这个不能说是转载吧,但是代码是别人的,所以就算是转载吧。 Regular Expression Matching Implement regular expression matchi...
  • qq_33792412
  • qq_33792412
  • 2017年03月29日 22:15
  • 244

LeetCode10. Regular Expression Matching有点难

Implement regular expression matching with support for '.' and '*'. '.' Matches any single characte...
  • booirror
  • booirror
  • 2016年01月23日 22:02
  • 870

leetcode之通配符

Wildcard Matching Implement wildcard pattern matching with support for '?' and '*'. '?' Match...
  • fangjian1204
  • fangjian1204
  • 2014年08月18日 17:55
  • 1045

leetcode10

Combination Sum II #coding=utf-8 class Solution(object): def combinationSum2(self, candidate...
  • s969966195
  • s969966195
  • 2017年07月28日 10:29
  • 51

Leetcode--easy系列10

#205 Isomorphic Strings Given two strings s and t, determine if they are isomorphic. Two str...
  • u010498696
  • u010498696
  • 2015年06月25日 21:46
  • 509

LeetCode(10)--RegularExpresssionMatching

方法转载自原博客 题目Implement regular expression matching with support for ‘.’ and ‘*’.样例‘.’ Matches any sin...
  • ruosiliu_123
  • ruosiliu_123
  • 2017年07月12日 21:28
  • 117

leetcode10-Regular Expression Matching之Java版本

我的leetcode之旅,该篇章主要完成使用Java实现算法。这是第10篇Regular Expression Matching...
  • peace1213
  • peace1213
  • 2016年09月12日 12:30
  • 855

leetcode 10 -- Regular Expression Matching

Regular Expression Matching 题目: Implement regular expression matching with support for ‘.’ and ...
  • wwh578867817
  • wwh578867817
  • 2015年05月28日 20:48
  • 874
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:LeetCode(10)RegularExpresssionMatching
举报原因:
原因补充:

(最多只允许输入30个字)