Implement wildcard pattern matching with support for '?'
and '*'
. (未 0902)
http://www.xuebuyuan.com/1936978.html
'?' 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
算法提交结果:Time Limit Exceeded
算法的思想:1): *S = *P or *P =‘?’时,S++, P++;
2): *P = '*' 时,保存当前最靠后(最新)的*的后面的一个数值 记为:start_P = P+1, start_S = 当前的S
3): 将 *S 与 *P 的值做比较,转1);若 *S 与 *P 的值不相等,则 重置 S 和 P 为start_S + 1 和start_P;
转 1),如此循环以上3步;
#include<iostream> using namespace std; class Solution { public: bool isMatch(const char *s, const char *p) { bool start = false; const char *start_s ; const char *start_p ; int pLen = 0; while (*s != '\0') { if (*p != '\0' &&( *s == *p || *p == '?')) { s++; p++; } if (start == true && *s != *p) { s = start_s + 1; while (*s != '\0' && *s != *start_p) s++; p = start_p; } else if (*p == '*') { start = true; while (*(p + 1) == '*' && *(p + 1) != '\0') p++; if (*(p + 1) == '\0') { return true; } else { p++; start_s = s; start_p = p; } } } if (*p == '\0' && *s == '\0') return true; else return false; } }; void main() { char *s = "abcdeade"; char *p = "abc***de"; Solution s1; bool f = s1.isMatch(s, p); cout << f << endl; }
改进:提交结果:accepted
思路还是跟上面的算法思想是一样的 ,见:isMatch2(),
描述:对于p = "c*ab*c",我们可以猜想出它可以匹配的s应该长成这样: "c....ab.....c",省略号表示0到任意多的字符。我们发现主要就是p的中间那个"ab"比较麻烦,一定要s中的'ab'来匹配,因此只要s中间存在一个"ab",那么一切都可以交给后面的'*'了。
所以说,当我们挨个比较p和s上的字符时,当我们遇到p的第一个'*',我们实际只需要不断地在s的剩余部分找和'ab'匹配的部分。
换言之,我们可以记录下遇到*时p和s的位置,记为presp和press,然后挨个继续比较*(++p)和*(++s);如果发现*p != *s,就回溯回去,p = presp,s = press+1, ++press;直到比较到末尾,或者遇到了下一个'*',如果遇到了下一个'*',说明 "ab"部分搞定了,下面的就交给第二个'*'了;如果p和s都到末尾了,那么就返回true;如果到末尾了既没遇到新的'*',又还存在不匹配的值,press也已经到末尾了,那么就返回false了。
#include<iostream> #include<time.h> using namespace std; class Solution { public: bool isMatch(const char *s, const char *p) { // 递归方法:time limit exceeded if (*s == '\0') { if (*p == '\0') return true; if (*p != '*') return false; } if (*s == *p || *p == '?') return isMatch(++s, ++p); else if (*p == '*') { while (*(++p) == '*'); for (; *s != '\0'; s++) if (isMatch(s, p)) return true; return false; } else return false; } bool isMatch2(const char *s, const char *p) { // accepted bool startFound = false; const char *pre_s = NULL; const char *pre_p = NULL; int pLen = 0; while (*s != '\0') { if (*s == *p || *p == '?') { s++; p++; } else if (*p == '*') { startFound = true; pre_s = s; pre_p = ++p; } else if (startFound == true && *s != *p) { s = ++pre_s; p = pre_p; } else return false; } while (*p == '*') p++; return *p == '\0'; } }; void main() { char *s = "abbaabbbbababaababababbabbbaaaabbbbaaabbbabaabbbbbabbbbabbabbaaabaaaabbbbbbaaabbabbbbababbbaaabbabbabb"; char *p = "***b**a*a*b***b*a*b*bbb**baa*bba**b**bb***b*a*aab*a**"; Solution s1; clock_t start = 0, end = 0; start = clock(); //bool f = s1.isMatch(s, p); bool f = s1.isMatch(s, p); end = clock(); cout << "总的运行时间是:" << (double)(end - start) ; cout << f << endl; }