《剑指offer》第十九题:正则表达式匹配
// 面试题19:正则表达式匹配 // 题目:请实现一个函数用来匹配包含'.'和'*'的正则表达式。模式中的字符'.' // 表示任意一个字符,而'*'表示它前面的字符可以出现任意次(含0次)。在本题 // 中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a" // 和"ab*ac*a"匹配,但与"aa.a"及"ab*a"均不匹配。 #include <cstdio> bool matchCore(const char* str, const char* pattern); bool match(const char* str, const char* pattern) { if (str == nullptr || pattern == nullptr) return true; return matchCore(str, pattern); } bool matchCore(const char* str, const char* pattern) { if (*str == '\0' && *pattern == '\0') //匹配完成 return true; if (*str != '\0' && *pattern == '\0') //模式匹配完 return false; if (*(pattern + 1) == '*') //如果下一位是* { if (*pattern == *str || (*pattern == '.' && *str != '\0')) //当前位匹配 { return matchCore(str + 1, pattern + 2) //判断下一个字符是否匹配 || matchCore(str + 1, pattern) //当前字符是否重复 || matchCore(str, pattern + 2); //判断当前字符是否与下一个模式匹配, 此时考虑当前模式重复0次 } else //如果第一位不匹配, 跳过* return matchCore(str, pattern + 2); } if (*pattern == *str || (*pattern == '.' && *str != '\0')) //第二位不是* return matchCore(str + 1, pattern + 1); return false; }
// ====================测试代码==================== void Test(const char* testName, const char* string, const char* pattern, bool expected) { if (testName != nullptr) printf("%s begins: ", testName); if (match(string, pattern) == expected) printf("Passed.\n"); else printf("FAILED.\n"); } int main(int argc, char* argv[]) { Test("Test01", "", "", true); Test("Test02", "", ".*", true); Test("Test03", "", ".", false); Test("Test04", "", "c*", true); Test("Test05", "a", ".*", true); Test("Test06", "a", "a.", false); Test("Test07", "a", "", false); Test("Test08", "a", ".", true); Test("Test09", "a", "ab*", true); Test("Test10", "a", "ab*a", false); Test("Test11", "aa", "aa", true); Test("Test12", "aa", "a*", true); Test("Test13", "aa", ".*", true); Test("Test14", "aa", ".", false); Test("Test15", "ab", ".*", true); Test("Test16", "ab", ".*", true); Test("Test17", "aaa", "aa*", true); Test("Test18", "aaa", "aa.a", false); Test("Test19", "aaa", "a.a", true); Test("Test20", "aaa", ".a", false); Test("Test21", "aaa", "a*a", true); Test("Test22", "aaa", "ab*a", false); Test("Test23", "aaa", "ab*ac*a", true); Test("Test24", "aaa", "ab*a*c*a", true); Test("Test25", "aaa", ".*", true); Test("Test26", "aab", "c*a*b", true); Test("Test27", "aaca", "ab*a*c*a", true); Test("Test28", "aaba", "ab*a*c*a", false); Test("Test29", "bbbba", ".*a*a", true); Test("Test30", "bcbbabab", ".*a*a", false); return 0; }
分析:*前一个字符重复任意次,开始理解为前面所有字符,就说题怎么越读越糊涂。
class Solution { public: bool match(char* str, char* pattern) { if (str == nullptr || pattern == nullptr) return true; return matchCore(str, pattern); } bool matchCore(char* str, char* pattern) { if (*str == '\0' && *pattern == '\0') return true; if (*str != '\0' && *pattern == '\0') return false; if (*(pattern + 1) == '*') { if (*str == *pattern || (*str != '\0' && *pattern == '.')) { return matchCore(str + 1, pattern + 2) || matchCore(str + 1, pattern) || matchCore(str, pattern + 2); } else return matchCore(str, pattern + 2); } if (*str == *pattern || (*str != '\0' && *pattern == '.')) return matchCore(str + 1, pattern + 1); return false; } };