Implement wildcard pattern matching with support for '?'
and '*'
.
'?' Matches any single character.
'*' Matches any sequence of characters (including the empty sequence).
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", "*") ? true
isMatch("aa", "a*") ? true
isMatch("ab", "?*") ? true
isMatch("aab", "c*a*b") ? false
class Solution {
public:
bool isMatch(const char *s, const char *p) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
int i , j, k;
int lengths,lengthp;
i=j=k=lengths=lengthp=0;
lengths=strlen(s);
lengthp=strlen(p);
if(lengths==0 && lengthp==0)
return true;
if(lengthp==1){
if(*p=='*')
return true;
else if(*p=='?'){
if(lengths==1)
return true;
else
return false;
}
else{
if(lengths==1)
return *s==*p;
else
return false;
}
}else{
if(*p=='?')
return isMatch(++s,++p);
else if(*p=='*'){
for(j=0 ; j<lengthp ; j++){
k|=isMatch(s+j,++p);
}
return k;
}
else{
if(*s==*p)
return isMatch(++s,++p);
else
return false;
}
}
}
};
上面这个递归是我自己写的,思路很简单了,主要分为以下几个关键的部分:
1. 当遇到?时,那么可以匹配任意的源字符串中的一个字符,我们只需递归的匹配下一个通配符串和下一个源字符串。
2. 当遇到*时,那么可以匹配任意的源字符串,那么我们就从0个字符开始递归匹配。
3. 最简单的是普通字符,那么直接匹配,再匹配下面的字符串。
发现一个不错的链接:
http://xoomer.virgilio.it/acantato/dev/wildcard/wildmatch.html
这里面介绍了一些不错的通配符匹配的算法,看了看他写的比我好多了!!!自己的代码确实跟屎一样。然后我就稍微把他的代码更改了一下,他似乎是一个极其热爱和平的人,哈哈哈哈:
class Solution {
public:
bool isMatch(const char *s, const char *p) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
while(*p){
switch(*p){
case '?':
// if(*s=='')
if(*s)return isMatch(++s,++p);
else return false;
break;
case '*':
for(p++;*p!='*';p++);
if(!*p)return true;
while(*s)if(isMatch(s++,p))return true;
return false;
default:
if(*s!=*p)return false;
break;
}
p++,s++;
}
for(;*p=='*';p++);
return ((!*p)&&(!*s));
}
};
这代码用到了递归,是不能通过大数据的。当然如果你认为这种代码就已经够简洁的话那你就图样图森破了。代码可以简洁到下面这个样子:
class Solution {
public:
bool isMatch(const char *s, const char *p) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
switch(*p){
case '\0':
return !*s;
case '*':
return isMatch(s,p+1) || *s && isMatch(s+1,p);
case '?':
return *s && isMatch(s+1,p+1);
default:
return (*s==*p) && isMatch(s+1,p+1);
}
}
};
上面的都是递归的解法,递归的解法效率永远是硬伤!下面介绍非递归的解法:
class Solution {
public:
bool isMatch(const char *s, const char *p) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
int i,star;
new_segment:
star=0;
if(*p=='*'){
star=1;
for(p++;*p=='*';p++);
}
test_match:
for(i=0 ; p[i] && (p[i]!='*');i++){
if(s[i]!=p[i]){
if(!s[i])return false;
if((p[i]=='?') && s[i]) continue;
if(!star)return false;
s++;
goto test_match;
}
}
if(p[i]=='*'){
s+=i;
p+=i;
goto new_segment;
}
if(!s[i])return true;
if(i && p[i-1]=='*') return true;
if(!star) return false;
s++;
goto test_match;
}
};
这里面用到了goto语句,我会考虑将goto去除的