把剑指offer上的代码全部展开,然后重写了一下并详细解释,感觉这样更好理解一些。
代码实现如下:
#include <iostream>
#include <assert.h>
using namespace std;
bool matchCore(char *str, char *pattern);
bool match(char* str, char* pattern) {
if (str == nullptr || pattern == nullptr) return false;
return matchCore(str, pattern);
}
bool matchCore(char *str, char *pattern) {
if (*str == '\0' && *pattern == '\0') // 全部匹配成功
return true;
if (*str != '\0' && *pattern == '\0') // 字符串还没匹配完,模式串pattern就已经没有了
return false;
if (*(pattern + 1) == '*') { // 特殊情况:如果pattern下一个字符为'*'
if (*pattern == *str) { // 如果*str等于*pattern,说明匹配成功
return matchCore(str, pattern + 2) // 情况1:我可以匹配0次,str指针不动,pattern指针向后移动
|| matchCore(str + 1, pattern + 2) // 情况2:我就匹配这一次,str指针向后移动,pattern指针也向后移动
|| matchCore(str + 1, pattern); // 情况3:我可以匹配多次:str指针向后移动,pattern指针不动。
}
else if (*pattern == '.' && *str != '\0') { // 如果*pattern表示任意字符,并且*str没结束,则肯定能够匹配成功啊
// 这波操作和上面完全一样
return matchCore(str, pattern + 2)
|| matchCore(str + 1, pattern + 2)
|| matchCore(str + 1, pattern);
}
else { // *str不等于*pattern,匹配失败,但*是可以允许匹配失败,所以跳过这部分pattern即可
return matchCore(str, pattern + 2);
}
}
else { // 普通情况:看看*str是否等于*pattern
if (*str == *pattern) // 如果*str 等于 *pattern
return matchCore(str + 1, pattern + 1) ; // 匹配成功,str与pattern同时向后移动
else if (*pattern == '.' && *str != '\0') // 如果*pattern是任意字符,且str未结束
return matchCore(str + 1, pattern + 1); // 同上
else // 匹配失败
return false; // 匹配是真的失败了
}
assert(0);
}
int main()
{
cout << match("aaa", "ab*aa") << endl;
system("pause");
}