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
这是难度比较高的一道题,思路需要及其的清晰,漏掉一个细节就AC不了。
首先,想到采用的方法是递归和不然会写奔溃的==
第一步是明确“.”和“*”的含义
".":匹配任意除换行符‘\n’外的字符;例如a.c可以匹配abc,也可以acc,etc;
"*":匹配前一个字符0词或无限次;这句话需要好好理解一下,这句话可以确定两点,第一“*”前面必定有一个字符,第二是可以匹配0次或无限次,比如“abc“*”,我想大多数人会误解为这个串可以匹配的最短字符是“abc”,事实上并不是这样的,最短能匹配的串是"ab",也就是说我们可以把“c*”看成是一个整体,这是一个误区。
明白这两个规则之后,就是分析字符串可能出现的情况,分为三种情况:
(1)p为空串,如果s也是空串,则匹配成功,返回true,否则返回false;
(2)p的下一个字符是*,这时候就需要判断p的当前字符和s的当前字符是否相等或者说当前字符是'.'并且s为非空,如果成立,需要判断跳过这个‘*’之后是否能匹配,匹配成功则返回true,否则s++;反之条件不成立则直接跳过'*';
(3)p的下一个字符不是'*',直接判断p和s的当前字符是否相等或者说p是‘.’,则直接跳到下一个字符,否则返回false;
思路还是比较清晰的,就是可能当时想的时候容易混乱,有一个比较好的方法是先不管'.',先把'*'写出来,然后再去考虑加上'.'之后,加上判断就好了。、
鉴于这种字符匹配指针比较好用,所以采用c语言来做。
bool isMatch(char* s, char* p) {
if (*p == '\0')
return *s=='\0';
if (*(p + 1) != '*'){
if (*s == *p || (*p == '.'&&*s != '\0'))
return isMatch(s + 1, p + 1);
else
return false;
}
else{
while (*s == *p || (*p == '.'&&*s != '\0')){
if (isMatch(s, p + 2))
return true;
++s;
}
return isMatch(s, p + 2);
}
}