您的位置:首页 > 其它

LEETCODE: Regular Expression Matching

2014-12-11 12:38 393 查看
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)

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

这题要考察的是正则表达式的匹配。我自己尝试写了一下,没有成功,只好网上找其他人的代码,因为我的理解和出题者的思路有些差别,或者我对正则表达式的理解原本就不是非常的准确。

1.正则表达式的第一个字符必须不是‘*’。

2.用来做匹配的字符串可以只和正则表达式的一部分进行匹配,就比如,“aab' 可以和 ”c*a*b" 进行匹配。

对于这样的一个题目,我们显然想到的就是递归了。那么,思路应该是如何的呢?

a. 假设现在p是末尾,我们只要看看s是否也已经是末尾,如果是的话,说明匹配成功,其实就是*s==*p=='\0'。这是递归结束的条件。

b. 假设p + 1 位置上的字符不是‘*’,说明当前的位置上的字符需要比较是否相等,或者p位置上的字符为‘.'。如果符合条件,对s + 1, p + 1 重新进行新的比较。

c. 假设p + 1 位置上的字符是’*‘, 如果p 位置上的字符和s + i (只要s + i还没有到字符串的末尾)的字符连续匹配,就把每一个 s + i和p + 2 进行匹配。

d. 如果 p 上的字符不等于s上的字符,并且p+1上的字符是*,那么就用s 和 p + 2进行匹配。

class Solution {
public:
bool isMatch(const char *s, const char *p) {
if(*p == '\0') return *s == '\0';

//if the next character is not '*'
if(*(p + 1) != '*'){
return (*s == *p || (*p == '.' && *s != '\0')) && isMatch(s + 1, p + 1);
}

//if the next character is '*'
while(*s == *p || (*p == '.' && *s != '\0')){
if(isMatch(s, p + 2)) return true;
s ++;
}

return isMatch(s, p + 2);
}
};

对于这个解法,其实我还是有些疑问的,比如,"baab" ,"a*b" 作为输入,那么就会返回false。"abaab" ,"a*b" 也是范围false。可能很多人和我也有同样的疑惑,但是上面的代码毕竟是可以通过测试的。所以我发现’*‘必须和它前面的那个字符一样,比如"aaab" ,"a*b"可以匹配,但是"aaabb" ,"a*b"不能。因为‘*’只能代表前面的a。
这样,我们可以做一下总结。

1. 两个字符串比较,如果已经到了末尾,就判定是否match。

2. 如果下一个字符不是‘*’,看当前的字符是否相等,不相等就是false,如果相等则两个字符串都后移再比较。

3. 如果下一个是‘*’,只要用来匹配的字符串当前连续位置上的字符等于‘*’之前的那个字符,就对他们和‘*’之后的字符串依次比较。

4. 如果下一个是‘*’,而两个字符串当前位置上的字符已经不相等,那么判断和‘*’之后的字符串是否有匹配的可能性。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息