題目描述
(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;
}
}
算法是速度是相當快的,在第一種情況下TLE的情況下,算法二僅僅需要 80ms,看來非遞歸的效率確實是很高的。