LeetCode 44 Wildcard Matching

把我難哭了 T Tspa

'?' 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

絞盡腦汁想出來一個方法是使用遞歸,可是會超時T^T萬惡的超時緣由很簡單,循環裏面套用遞歸,不超時纔怪。可是仍是把方法粘貼出來:
 1 bool satisfyCondition(string p){//判斷p是否全由*組成
 2     bool satisfy = true;
 3     for(int i = 0 ;i < p.length();i++){ //need p to be a form of ?********
 4         if(p[i]!='*'){
 5             satisfy = false;
 6             break;
 7         }
 8     }
 9     return satisfy;
10 }
11 
12 string getSubStrFromIndexToEnd(string s, int a){//從P尾截取長度爲a的串
13     string resultStr = "";
14     for(int i  = a;i < s.length();i++){
15         resultStr+=s[i];
16     }
17     return resultStr;
18 }
19 
20 
21 bool isMatch(string s, string p) {
22     int len1 = s.length();
23     int len2 = p.length();
24     bool goodResult = false;
25     if(len1==len2 && len1 == 0) //均空串
26         return true;
27     if(p[0] != '?' && p[0] != '*'){//均普通字符串
28         if(p[0]!=s[0])
29             return false;
30         else
31             return isMatch(getSubStrFromIndexToEnd(s, 1),getSubStrFromIndexToEnd(p, 1));
32     }
33     else if(p[0] == '?'){
34         if (len1 == 0) return false;
35         if (len1==1)//判斷?以後的是否是都是*
36         {
37             if (satisfyCondition (getSubStrFromIndexToEnd(p, 1)))
38                 return true;
39             else
40                 return false;
41         }
42         else
43             return isMatch(getSubStrFromIndexToEnd(s,1),getSubStrFromIndexToEnd(p, 1));
44     }
45     else{//p[0]=='*'
46         for(int i = len1 ;i>=0;i--){//遇到*則進入循環,用貪心的策略,先假設*能夠代替s整個串,來看看行不行(*代替整串則s只剩空,判斷空串與p剩下的是否match),不行則假設*能夠代替短一點的串,此時s只剩最後一個字符,再與p剩下的match,以此類推,找到一個match的就能夠了
47             if(isMatch(getSubStrFromIndexToEnd(s,i),getSubStrFromIndexToEnd(p,1))){
48                 goodResult =  true;
49                 break;
50             }
51             else
52                 goodResult =  false;
53         }
54         return goodResult;
55     }
56 }

目前還在想第二種方法。。。。prototype

耗時5小時總算想出來了。。。。code

前面一種方法用的遞歸,下面的方法用的是迭代,要比遞歸快的多。orm

bool isMatch(string s, string p) {
    int len1 = s.length();
    int len2 = p.length();
    int i = 0; //point to s
    int j = 0; //point to p
    bool afterStar = false;
    int afterStarPosS = 0;// 遇到*時s當前遍歷的數字位置索引,這個數會改變
    int afterStarPosP = 0;//標記*後的位置索引
    if(s == p) return true;
    while(i<len1){
        if(j<len2){
            if(s[i]==p[j]||p[j]=='?'){
                i++;
                j++;
            }
            else if(s[i]!=p[j] && p[j]!= '?'&& p[j]!= '*' && !afterStar){
                return false;//若是歷來沒遇到過*就碰上不同的字符則不匹配
            }
            else if(s[i]!=p[j] && p[j]!= '?'&& p[j]!= '*' && afterStar){
                j = afterStarPosP;//若是遇到過*,則說明假設*所能替代的字符串不對,
                                  //須要把J設置到*後的位置從新開始遍歷,並從新設置i的值,afterStarPosS自增可使下一次從新遍歷時i的開始位置加和如今比加一,這樣表明*所替代的                                    字符串長度加一
                i = afterStarPosS;
                afterStarPosS++;
            }
            else{// p[j]='*'
                while(j<len2-1 && p[j+1]==p[j] && p[j]== '*' )
                    j++;//遇到*則看是否是後面都是*,是則確定match
                if(j == len2-1)// all behind are '*'
                    return true;
                afterStarPosP = j+1;//設置洗的afterStarPosP、S值,能走到這一步說明以前的匹配都成功了
                afterStarPosS = i;
                afterStar = true;
                j++;
            }
        }
        else{//i<len && j==len2
            if(afterStar){//遇到p先走到結尾則說明匹配是不成功的,須要從新設置i,j
                j = afterStarPosP;
                i = afterStarPosS;
                afterStarPosS++;
            }
            else//若是以前連*都沒碰到就這樣了,則確定錯了
                return false;
        }
    }
    
    while(p[j]=='*') j++;//s先到結尾時看p是否都是*,是則true不然false
    if(j == len2)
        return true;
    else
        return true;
}
   

不容易啊!blog

相關文章
相關標籤/搜索