'?' Matches any single character.
'*' Matches any sequence of characters(including the empty sequence).
The matching should cover the entireinput 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", "*")→ true
isMatch("aa","a*") → true
isMatch("ab","?*") → true
isMatch("aab","c*a*b") → false
Given [0,1,0,2,1,0,1,3,2,1,2,1],return 6.
思路:本题与《Regular Expression Matching》类似,解题思路也可以照搬:在模式p中,一旦遇到字符’*’,就将从p+1开始于s+i(i=0,1,2,...)进行匹配,直到找到匹配的位置。但是需要注意一点,如果到了s的最后还是没能匹配的话,整个匹配过程就应该结束了,不应该在回退回去,去看s+i+1是否与p+1匹配,因为是没有意义的,代码如下:
int isMatchcore(char*s, char* p, int *exitflag)
{
if(*s == ' ')
{
if(*p == ' ') return 1;
if(*p == '*' &&*(p+1) == ' ') return 1;
*exitflag = 1;
return 0;
}
if(*p != '*')
{
if(*p == *s ||*p == '?') returnisMatchcore(s+1, p+1, exitflag);
return 0;
}
if(*p == '*')
{
if(*(p+1) ==' ') return 1;
int i = 0;
int slen = strlen(s);
while(i < slen &&(isMatchcore(s+i, p+1, exitflag)== 0))
{
if(*exitflag == 1)
{
return 0;
}
i++;
}
if(i < slen) return 1;
return 0;
}
}
void predealpattern(char*p)
{
int i = 0;
int plen = strlen(p);
int j = 0;
int lastchar = 0;
for(i = 0; i <=plen; i++)
{
if(p[i] != '*'|| lastchar != '*')
{
p[j] = p[i];
j++;
}
lastchar = p[i];
}
}
int isMatch_recurse(char*s, char* p)
{
predealpattern(p);
int exitflag = 0;
return isMatchcore(s, p,&exitflag);
}predealpattern函数用来对模式进行预处理,对于一连串的’*”,比如’****’,只保留一个’*’。这样做是为了减少递归的次数。exitflag的作用就是,一旦匹配到了s的最后还没有匹配成功,则整个匹配过程就应该结束了。开始没有注意到这一点,则在leetcode上测试直接超时。该递归程序最后的测试时间是16ms。下面是非递归版本,原理上是类似的,时间上更快一些,为8ms:
int isMatch_loop(char*s, char* p)
{
char *lastp = NULL;
char *lasts = NULL;
while(*s != ' ')
{
if(*s == *p ||*p == '?')
{
s++; p++;
}
else if(*p == '*')
{
p++;
if(*p == ' ') return 1;
lastp = p;
lasts = s;
}
else if(lastp != NULL)
{
p = lastp;
s = ++lasts;
}
else
{
return 0;
}
}
while(*p == '*')p++;
return *p == ' ';
}
参考:
https://github.com/haoel/leetcode/tree/master/algorithms/wildcardMatching