Regular Expression Matching
2014-02-19 05:53
417 查看
'.' 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
使用递归。
对于 pattern p, indexP 对应当前访问的 char, indexP + 1 对应下一个 char.
case 1 : if (p.charAt(indexP + 1) != '*')
如果下一个 char (char at indexP + 1) 不是 ‘*’, 即 if (p.charAt(indexP + 1) != '*'), 那么必须要求当前的 char at indexP 和 char at indexS 是对应的。
例如: s: ...... a b......
p: ...... cc
......
pp+1
这里 index p+1 的位置, char != '*' , 那么如果 在 index p 的位置上不对应, 则直接返回 false, 因为到这一层 p之前的部分匹配成功,但到p 的位置,匹配已经失败了,而且 p + 1 不是 ‘*’, 没法跳过 p。
例如: s: ...... a b
......
p: ...... ac
......
p p+1
在这个例子中,p 的位置对应的 char 是一样的,匹配成功,那么就进入下一层递归调用matchHelper(s, p, indexS + 1, indexP + 1)。
至于 p + 1 位置上的 b 和 c 不对应,那是下一层递归的任务,当进入下一层后,原来的 p + 1 就变成了 p。
case 2 : if (p.charAt(indexP + 1) == '*')
第二种情况是,当下一个 char 是 ‘*’ 时。
此时意味着当前index 对应的 char 可以出现0次或者多次。
但是到底是匹配几个才是最后成功匹配的个数呢?
例如:
s:
a a ab
p: a
* b
用 * 匹配了三个。
s:
a a ab
p: a
* a b
用 * 匹配了两个个。
在没有进行后续部分的比较前,没法确定到底应该用 * 匹配几个,才是应该使用的正确个数。因此方法就是把所有可能匹配上的个数都试一遍。因此 从 0 ~ n 个可以用 * 匹配上 s 的后续的 char 的,都调用一次递归,如果某一种个数最后成功完成了匹配,就 return true, 否则继续用 * 匹配 s 的下一个 char.
直到 s 中 所有可以与当前 * 匹配的都匹配完,即失去与 * 的匹配后,却没有一次成功的匹配并return true. 则跳过 * (indexP + 2),继续后续的递归:
// until we get char at indexS != charAt indexP
return matchHelper(s, p, indexS, indexP + 2);
s s+1s+2s+3s+4
例子: s: ...... a a
a ac ......
p: ...... a*
......
p p+1p + 2
这里 p + 1 是 ‘*’
循环第一次,调用 if (matchHelper(s, p, indexS, indexP + 2)) {return true;},也就是 a* 没有和 s ... s+4 的任何一个a匹配,直接跳过
循环第二次, s++, 此时indexS指在 s + 1. 也就是 a* 匹配了一个 a, 然后跳过a*, 进入后续的比较
循环第三次 s++, 此时indexS指在 s + 2. 也就是 a* 匹配了两个 a, 然后跳过a*, 进入后续的比较
...
(这期间如果有一次的组合是证明成功的,就会return true,因为在 if 里调用了递归)
最后 indexS 到 s + 4(a* 匹配了s中所有可以匹配的a), 此时说明之前的几次都没匹配成功,则继续进入后续的调用:
// until we get char at indexS != charAt indexP
return matchHelper(s, p, indexS, indexP + 2);
'*' 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
使用递归。
对于 pattern p, indexP 对应当前访问的 char, indexP + 1 对应下一个 char.
case 1 : if (p.charAt(indexP + 1) != '*')
如果下一个 char (char at indexP + 1) 不是 ‘*’, 即 if (p.charAt(indexP + 1) != '*'), 那么必须要求当前的 char at indexP 和 char at indexS 是对应的。
例如: s: ...... a b......
p: ...... cc
......
pp+1
这里 index p+1 的位置, char != '*' , 那么如果 在 index p 的位置上不对应, 则直接返回 false, 因为到这一层 p之前的部分匹配成功,但到p 的位置,匹配已经失败了,而且 p + 1 不是 ‘*’, 没法跳过 p。
例如: s: ...... a b
......
p: ...... ac
......
p p+1
在这个例子中,p 的位置对应的 char 是一样的,匹配成功,那么就进入下一层递归调用matchHelper(s, p, indexS + 1, indexP + 1)。
至于 p + 1 位置上的 b 和 c 不对应,那是下一层递归的任务,当进入下一层后,原来的 p + 1 就变成了 p。
case 2 : if (p.charAt(indexP + 1) == '*')
第二种情况是,当下一个 char 是 ‘*’ 时。
此时意味着当前index 对应的 char 可以出现0次或者多次。
但是到底是匹配几个才是最后成功匹配的个数呢?
例如:
s:
a a ab
p: a
* b
用 * 匹配了三个。
s:
a a ab
p: a
* a b
用 * 匹配了两个个。
在没有进行后续部分的比较前,没法确定到底应该用 * 匹配几个,才是应该使用的正确个数。因此方法就是把所有可能匹配上的个数都试一遍。因此 从 0 ~ n 个可以用 * 匹配上 s 的后续的 char 的,都调用一次递归,如果某一种个数最后成功完成了匹配,就 return true, 否则继续用 * 匹配 s 的下一个 char.
直到 s 中 所有可以与当前 * 匹配的都匹配完,即失去与 * 的匹配后,却没有一次成功的匹配并return true. 则跳过 * (indexP + 2),继续后续的递归:
// until we get char at indexS != charAt indexP
return matchHelper(s, p, indexS, indexP + 2);
s s+1s+2s+3s+4
例子: s: ...... a a
a ac ......
p: ...... a*
......
p p+1p + 2
这里 p + 1 是 ‘*’
循环第一次,调用 if (matchHelper(s, p, indexS, indexP + 2)) {return true;},也就是 a* 没有和 s ... s+4 的任何一个a匹配,直接跳过
循环第二次, s++, 此时indexS指在 s + 1. 也就是 a* 匹配了一个 a, 然后跳过a*, 进入后续的比较
循环第三次 s++, 此时indexS指在 s + 2. 也就是 a* 匹配了两个 a, 然后跳过a*, 进入后续的比较
...
(这期间如果有一次的组合是证明成功的,就会return true,因为在 if 里调用了递归)
最后 indexS 到 s + 4(a* 匹配了s中所有可以匹配的a), 此时说明之前的几次都没匹配成功,则继续进入后续的调用:
// until we get char at indexS != charAt indexP
return matchHelper(s, p, indexS, indexP + 2);
public boolean matchHelper(String s, String p, int indexS, int indexP) { // 当匹配进行到最后,s 和 p的指针超出了末尾 if (indexP == p.length()) { return indexS == s.length(); } // 当匹配进行到最后,s 和 p的指针到达了末尾,且相等 if (indexP == p.length() - 1) { return indexS == s.length() - 1 && (s.charAt(indexS) == p.charAt(indexP) || p.charAt(indexP) == '.'); } // next char != '*' // 若此时 s 和 p 匹配不上,则return false if (p.charAt(indexP + 1) != '*') { if (indexS < s.length() && (s.charAt(indexS) == p.charAt(indexP) || p.charAt(indexP) == '.')) { return matchHelper(s, p, indexS + 1, indexP + 1); } else { return false; } } else { // next char == '*' // 用 while loop 和 递归把所有匹配的个数都尝试一遍 while (indexS < s.length() && (s.charAt(indexS) == p.charAt(indexP) || p.charAt(indexP) == '.')) { if (matchHelper(s, p, indexS, indexP + 2)) { return true; } indexS++; } // until we get char at indexS != charAt indexP // 之前的递归调用都没有返回 true, // 此时 * 匹配了当前 s 中后续所有可以匹配的重复char, 跳过 * 继续往后 return matchHelper(s, p, indexS, indexP + 2); } } public boolean isMatch(String s, String p) { return matchHelper(s, p, 0, 0); }
相关文章推荐
- LeetCode "Regular Expression Matching"
- 66. Regular Expression Matching
- leetcode第十题--Regular Expression Matching
- Leetcode: Regular Expression Matching
- leetcode Regular Expression Matching
- leetcode——Regular Expression Matching
- Regular Expression Matching
- Regular Expression Matching--LeetCode
- Regular Expression Matching
- LeetCode 10 - Regular Expression Matching
- [eetcode 10]Regular Expression Matching
- Regular Expression Matching
- ***Regular Expression Matching
- LeetCode Problem10 Regular Expression Matching
- Regular Expression Matching
- [LeetCode]Regular Expression Matching
- LeetCode : Regular Expression Matching [java]
- leetcode Regular Expression Matching
- LeetCode OJ --- Regular Expression Matching
- LeetCode之10 --- Regular Expression Matching