leetcode

leetcode solutions for entertainment value
Log | Files | Refs

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 }