LeetCode(10)RegularExpresssionMatching
来源:互联网 发布:淘宝网数码相机 编辑:程序博客网 时间:2024/05/29 09:12
我觉这道题目得挺难的,想了很久也没想清楚%>_<%于是看了解题报告
题目解释
'.' 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)RegularExpresssionMatching
- LeetCode(10)--RegularExpresssionMatching
- Leetcode(10)
- LeetCode #10
- leetcode 10: Triangle
- [LeetCode] Valid Palindrome [10]
- leetCode(10):Partition List
- Leetcode--easy系列10
- leetCode练习(10)
- 10 leetcode - Palindrome Number
- Leetcode日记(10)
- LeetCode-10(回文检测)
- leetcode week 10
- leetcode-10-正则表达式
- [Leetcode] 10, 44, 69
- 4.10 leetcode -10 triangle
- LeetCode刷题(10)
- Leetcode个人题解10
- boost智能指针系列:scoped_ptr
- C++ SQLite安装与使用,以及一个小实例
- repo init error: could not verify the tag 'v1.12.7'
- 关于modprobe的相关。
- 职业生涯规划与自我管理
- LeetCode(10)RegularExpresssionMatching
- 调试控制台程序
- 用foe循环求100到200之间的素数
- 杭电acm阶段之理工大版--第一阶段开始入门解题代码(1)
- [Android] ActionBar的使用
- 电话本--------分离命令和输入参数
- 仿uc下部弹出菜单
- 什么是Windows能干而Linux干不了的事情
- nodejs创建项目