'?'
and
'*'
.
'?' 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
思路:
应该可以用动态规划的方法来处理。
题解:
class Solution { public: bool isMatch (const char* s, const char* p) { if (s == 0 || p == 0) return false; while (true) { if (*s == 0 && *p == 0) return true; if (*p == 0) return false; if (*p == '?' || *p == *s) { ++s, ++p; } else if (*p == '*') { const char* next_p = p + 1; while (*next_p == '*' && *next_p != 0) ++next_p; if (*s == 0) return *next_p == 0; else { if (*next_p == '?') return isMatch (s, next_p) || isMatch (s + 1, p); else if (*next_p != 0) { const char* next_s = s; bool valid = false; while (*next_s != 0) { if (*next_s == *next_p && isMatch (next_s + 1, next_p + 1)) { valid = true; break; } ++next_s; } return valid; } else return true; } } else return false; } } };思路:
上述方法是超时的。没有办法。不过考虑到其实可以把pattern以*为间隔分块,然后在字符串里看是否这些块按顺序出现,当然开头和结尾的部分要特殊处理一下。比如结尾的块不是'*',那么就必须按照倒序检查原始字符串末尾的字符。
题解:
class Solution { public: #define charMatch(s, p) (p == '?' || p == s) int subStr (const char* s, int start, const char* p, int len) { while (s[start] != 0) { if (charMatch (s[start], p[0])) { bool match = true; for (int j = 1; j < len; ++j) if (s[start + j] == 0) return -1; else if (!charMatch (s[start + j], p[j])) { match = false; break; } if (match) return start + len; } ++start; } return -1; } #undef charMatch bool isMatch (const char* s, const char* p) { bool front_vary = *p == '*'; bool back_vary = false; int s_offset = 0; int p_start = 0; int p_offset = 0; while (p[p_offset] != 0) { p_start = p_offset; while (p[p_start] == '*' && p[p_start] != 0) ++p_start; if (p[p_start] == 0) { // is pattern empty? if (p_start != 0) back_vary = p[p_start - 1] == '*'; break; } p_offset = p_start + 1; while (p[p_offset] != '*' && p[p_offset] != 0) ++p_offset; if (p[p_offset] == 0 && p_start != 0) { // for the last block we need to do matching backwards int old_soffset = s_offset; while (s[s_offset] != 0) ++s_offset; int pi = p_offset; int si = s_offset; while(pi >= p_start && si >= old_soffset) { if (p[pi] != '?' && p[pi] != s[si]) return false; --pi, --si; } if (pi >= p_start) return false; // s does not have enough space } else { s_offset = subStr (s, s_offset, p + p_start, p_offset - p_start); if (s_offset == -1 || (p_start == 0 && !front_vary && s_offset != p_offset - p_start)) return false; } } if (!back_vary && s[s_offset] != 0) return false; else return true; } };