把我難哭了 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