10.c (3509B)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <stdbool.h> 4 #include <string.h> 5 6 #define DEBUG 0 7 #define PDEBUG(...) if (DEBUG) printf(__VA_ARGS__) 8 9 #define HTLEN 3000 10 11 static bool isMatchInternal(char* s, char* p, int depth) { 12 PDEBUG("isMatch [%s] [%s] depth %d\n", s, p, depth); 13 // fully recursive solution... 14 // look ahead, how many characters could 15 int pl = strlen(p); 16 int pn = -1; 17 if (pl > 1) { 18 pn = p[1]; 19 } 20 21 if (s[0] == '\0') { 22 // if we're at the end of the pattern 23 if (p[0] == '\0') { 24 return true; 25 } 26 // OR the next is * then recurse again.. 27 if (pn == '*') { 28 return isMatchInternal(s, p+2, depth+1); 29 } 30 // otherwise there is remaining unmatched pattern, so we're not a match 31 return false; 32 } else if (pn == '*') { 33 // how many characters _could_ we match? 34 int n = 0; 35 while ((s[n] == p[0] || p[0] == '.') && s[n] != '\0') { 36 n++; 37 } 38 // try each option 39 for (int i=0; i<=n; i++) { 40 PDEBUG("trying i %d\n", n); 41 if (isMatchInternal(s+i, p+2, depth+1)) { 42 return true; 43 } 44 } 45 return false; 46 } else if (s[0] == p[0] || p[0] == '.') { 47 PDEBUG("s[0] [%c] p[0] [%c] incrementing\n", s[0], p[0]); 48 return isMatchInternal(s+1, p+1, depth+1); 49 } else { 50 return false; 51 } 52 } 53 54 bool isMatch(char* s, char* p) { 55 return isMatchInternal(s, p, 0); 56 } 57 58 // bool isMatch(char* s, char* p) { 59 // PDEBUG("isMatch %s %s\n", s, p); 60 // int sx = 0, px = 0; 61 // int pl = strlen(p); 62 // int sl = strlen(s); 63 // while (s[sx] != '\0' && p[px] != '\0') { 64 // int pn = -1; 65 // if ((px+1) < pl) { 66 // pn = p[px+1]; 67 // } 68 // if (pn == '*') { 69 // PDEBUG("s[sx] %c p[px] %c pn %c\n", s[sx], p[px], pn); 70 71 // // is this the end of the pattern? 72 // if ((px+2) == pl) { 73 // PDEBUG("* at end of string\n"); 74 // // just check all the remaining characters match 75 // bool res = true; 76 // for (int i=sx; i<sl; i++) { 77 // res = res && (s[i] == p[px] || p[px] == '.'); 78 // } 79 // return res; 80 // } else { 81 // // how many characters _could_ we match?? 82 // int sxx = sx; 83 // while ((s[sxx] == p[px] || p[px] == '.') && s[sxx] != '\0') { 84 // sxx++; 85 // } 86 // // recursively match the remaining trying each possible number of matches. 87 // // god this could be slow. 88 // for (int i=sx; i<(sxx+1); i++) { 89 // if (isMatch(s+i, p+px+2)) { 90 // return true; 91 // } 92 // } 93 // return false; 94 // } 95 // } else { 96 // PDEBUG("s[sx] %c p[px] %c\n", s[sx], p[px]); 97 // if (s[sx] == p[px] || p[px] == '.') { 98 // sx++; 99 // px++; 100 // } else { 101 // return false; 102 // } 103 // } 104 // } 105 // // now verify we're at the end of both strings, OR we're at the last character of p and it's a * 106 // bool res = s[sx] == '\0' && p[px] == '\0'; 107 // PDEBUG("isMatch %s\n", res ? "true": "false"); 108 // return res; 109 // } 110 111 void test(char* s, char* p, bool exp) { 112 bool act = isMatch(s, p); 113 if (act != exp) { 114 fprintf(stderr, "test s %s p %s failed, exp %s act %s\n", s, p, exp ? "true": "false", act ? "true" : "false"); 115 } 116 } 117 118 int main() { 119 { 120 test("aa", "p", false); 121 } 122 { 123 test("aa", "a*", true); 124 } 125 { 126 test("ab", ".*", true); 127 } 128 { 129 test("aab", "a*", false); 130 } 131 { 132 test("aab", "a*b", true); 133 } 134 { 135 test("aaaaaab", "a*b", true); 136 } 137 { 138 test("aaaaaab", "a*b*", true); 139 } 140 { 141 test("aaaaaabc", "a*b*", false); 142 } 143 { 144 test("aaaaaabc", "a*b*.", true); 145 } 146 { 147 test("aab", "c*a*b", true); 148 } 149 { 150 test("aaa", "a*a", true); 151 } 152 { 153 test("a", "ab*", true); 154 } 155 { 156 test("abcaaaaaaabaabcabac", ".*ab.a.*a*a*.*b*b*", true); 157 } 158 }