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
动态规划请参考:动态规划解法
递归方法:(TLE)
class Solution {
public:
bool isMatch(const char *s, const char *p) {
if( 0 == *p) return 0 == *s;
if(*p == '*'){
while(*(p+1) == '*')p++;
while((*s) != 0){
if(isMatch(s,p+1))return true;
s++;
}
return isMatch(s,p+1);
}
else{
if(((*s) != 0) && ((*s) == (*p) || (*p) == '?')){
return isMatch(s+1,p+1);
}
return false;
}
}
};
水平有限,调代码调的比较久,边界问题总是弄不清楚,要死的节奏。
这里当前面和后面均有*号的时候,本来想用kmp,可是KMP也不是很熟,而且这里还有?号。
总体思想是:分析 p 串,把其中每个单词均解析出来,然后用贪心的方法进行匹配,匹配后要保存匹配到 s 中的位置。
总体还是过了,232ms,前面的递归方法TLE。
贪心方法:
class Solution {
public:
bool isMatch(const char *s, const char *p) {
//greedy
bool pre,next;
const char *start,*end,*mid;
const char *ss,*se,*sm;
start = p;
end = p;
ss = s;
while(true){
if(*start == '*')pre = true;//查看前面有没有*
else pre = false;
//查看新的没有*的word
while(*start != '\0' && *start == '*')start++;
end = start;
while(*end != '\0' && *end != '*')end++;
if(*end == '*')next = true;
else next = false;
end--;
if(*ss == '\0' && pre && *start == '\0')return true;//p和s均完全匹配
if(*ss != '\0' && pre && *start == '\0')return true;
if(*ss != '\0' && (*start == '\0' && !pre))return false;//s没能完全匹配
if(*ss == '\0' && *start != '\0')return false;//p的字母没能匹配完全
//处理greedy匹配问题
if(next == true){//后面有*可供匹配
if(pre == true){//前面有供做匹配的
sm = ss,mid = start;//判断s中剩余的还够匹配不够
while(mid != end && *sm != '\0'){
mid++,sm++;
}
if(*sm == '\0')return false;
mid = start;
while(*mid != '*' && *ss != '\0'){
for(sm = ss,mid = start;*sm != '\0' && *mid != '*';sm++,mid++){
if(*mid == '?')continue;
if(*mid != *sm)break;
}
if(*mid == '*')ss = sm;
else ss++;
}//while
if(*mid != '*')return false;
ss = sm;
start = mid;
}
else{//前面没有供匹配的
for(sm = ss,mid = start;*sm != '\0' && mid != end+1;sm++,mid++){
if(*mid == '?')continue;
if(*mid != *sm)return false;
}
if(mid != end+1)return false;
ss = sm;//匹配成功
start = end+1;
}
}
else{//最后必须匹配的一串,因为后面没有*可供匹配最后的字母
if(pre){
se = ss;
while(*se != '\0')
se++;
se--;
for(sm = se,mid = end;mid != start && sm != ss;mid--,sm--){
if(*mid == '?')continue;
if(*mid != *sm)return false;
}
if((sm == ss && mid != start) || (*mid != *sm && *mid != '?'))return false;//如果s不够匹配或者p开头不能匹配
return true;
}
else{
for(sm = ss,mid = start;*sm != '\0' && *mid !='\0';sm++,mid++){
if(*mid == '?')continue;
if(*mid != *sm)return false;
}
if(*sm != '\0' || *mid != '\0')return false;
return true;
}
}
}
}
};