(http://www.leetcode.com/onlinejudge 倒数第三题)
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
这个题目的非递归算法,被网易有道面试官,面到过。并且要求写出程序,其实非递归算法要考虑的东西还是很多的,如果没有见过算法,真是很难写出来。笔者在这里给出递归和非递归算法。仅供参考
和正则表达式的匹配有点不同的是,在这里*号是不依赖与以前的符号是,是一个通配符。*是一个多重通配符,而*是一个单一通配符。
其实题目很容易写出一个递归的方法:
递归方法首先检查输入两个串是否都是空,如果是空,认为已经匹配完毕,直接返回true。
如果被匹配串是空,模式串如果是 *, 那么是true
如果模式串是空,那么结果是false
class Solution { public: bool isMatch(const char *s, const char *p) { if(*s == 0 && *p == 0){ //两个串是否都是空,如果是空,认为已经匹配完毕,直接返回true。 return true; } if(*s == 0){ //如果被匹配串是空,模式串如果 全是*,那么就是true while(*p == '*') p++; return !(*p); } if(*p == 0){ return false; } int i; for( i = 0; s[i] && p[i] ; i++){ //匹配过程 if(s[i] != p[i]){ if(p[i] == '?'){ //单一通配符 continue; } else if(p[i] == '*'){ //多重通配符 s += i; p += i; return isMatch(s, p + 1) || isMatch(s + 1, p);//匹配和不匹配,两种情况 } else{ return false; } } } return isMatch(s + i, p + i); //匹配剩余的 } };
while(p[i] == '*')i++; return !(p[i]);}
bool isMatch(const char *s, const char *p) { int i; bool star = false; startLoop: { for( i = 0; s[i] ; i++){ switch(p[i]) { case '?': break; case '*': //如果当前 为*, 那么匹配上刚刚不能匹配的那个字符,并且将p移动到 * 结束后的 第一个字符 star = true; //p 每次指向的位置,要么是最开始,要么是 * 结束的第一个位置 p += i; s += i; while(*p == '*'){++p;} //检测p是不是后面全是 * if(!(*p)) return true; goto startLoop; //重新开始循环, p 指向 * 结束后的 第一个 非* default: if(s[i] != p[i]){ //如果 s[i] != p[i] goto starCheck; } } } } while(p[i] == '*')i++; return !(p[i]); starCheck: { if(star){ //当 s[i] != p[i], 检测 p 之前是不是 *, 如果是 *,那么我们将s 向后移动一个,其实就是枚举 s 到 s[i],和 p[0] 匹配。 s++; goto startLoop; } return false; } }