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; } };