@@ -32,35 +32,31 @@ using namespace std;
3232
3333
3434bool isMatch (const char *s, const char *p) {
35-
36- bool star = false ;
37- const char *s1, *p1;
38- while ( *s && (*p || star) ){
39- if (*p==' ?' || *s == *p){
40- s++; p++;
41- }else if (*p==' *' ){
42- // skip the "*", and mark a flag
43- star = true ;
35+ const char *last_s = NULL ;
36+ const char *last_p = NULL ;
37+ while (*s != ' \0 ' ) {
38+ // Here, '*' in the pattern is ungreedy. This means we are trying to
39+ // build one or more one-character-to-one-character mappings between
40+ // the pattern string and the target string as much as possible.
41+ if (*p == ' *' ) {
42+ last_s = s;
43+ last_p = p++;
44+ } else if (*p == ' ?' || *p == *s) {
45+ s++;
4446 p++;
45- // edge case
46- if (*p==' \0 ' ) return true ;
47- // use s1 and p1 to store where the "*" match starts.
48- s1 = s;
49- p1 = p;
50- }else {
51- if (star==false ) return false ;
52- // if meet "*" previously, but the *s != *p
53- // reset the p, using '*' to match this situation
54- p = p1;
55- s = ++s1;
47+ } else if (last_s) {
48+ // Why not use stacks? Because '*' is ungreedy and it can match any
49+ // character. If s becomes '\0' and the rest of p contains
50+ // characters other than '*', that means:
51+ // len(original_s) < len(original_p) - count(original_p, '*')
52+ s = ++last_s;
53+ p = last_p + 1 ;
54+ } else {
55+ return false ;
5656 }
5757 }
58- // edge case: "s" is done, but "p" still have chars.
59- if (*s==' \0 ' ) {
60- while (*p==' *' ) p++; // filter all of '*'
61- if (*p==' \0 ' ) return true ;
62- }
63- return false ;
58+ while (*p == ' *' ) p++;
59+ return *p == ' \0 ' ;
6460}
6561
6662
@@ -89,6 +85,11 @@ int main(int argc, char** argv)
8985 s = " a" ;
9086 p = " a**" ;
9187 cout << s << " , " << p << " : " << isMatch (s, p) << endl;
88+
89+ s = " *aa" ;
90+ p = " *a" ;
91+ cout << s << " , " << p << " : " << isMatch (s, p) << endl;
92+
9293 if (argc>2 ){
9394 s = argv[1 ];
9495 p = argv[2 ];
0 commit comments