面试题19:正则表达式匹配。请实现一个函数用来匹配包括’.‘和’*‘的正则表达式。模式中的’.‘表示任意一个字符,而’*'表示它左面的一个字符可以出现任意次(含0次),本题中,匹配是指字符串的所有字符匹配整个模式,即模式中有一种情况与要匹配的串相同则匹配成功。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但与"aa.a"和"ab*a"均不匹配。
当模式中的第二个字符不是’*'时:
1、如果字符串第一个字符和模式中的第一个字符相匹配,那么字符串和模式都后移一个字符,然后匹配剩余的。
2、如果字符串第一个字符和模式中的第一个字符不匹配,直接返回false。
而当模式中的第二个字符是’*'时,可以有3种匹配方式:
1、模式后移2字符,相当于x*被忽略;
2、字符串后移1字符,模式后移2字符,x*相当于只匹配一个字符;
3、字符串后移1字符,模式不变,即继续匹配字符下一位,因为*可以匹配多位;
#include <iostream>
using namespace std;
bool MatchCore(const char* str, const char* pattern) {
if (*str == '\0' && *pattern == '\0') {
return true;
}
if (*pattern == '\0' && *str != '\0') { //在pattern结束时若str还没结束,则不匹配
return false; //但当str结束,pattern还没结束,可能pattern还有类似a*的可以为空的子串,不能判断是否结束
}
if (*(pattern + 1) == '*') {
if (*str == *pattern || (*pattern == '.' && *str != '\0')) {
return MatchCore(str + 1, pattern) //当a*匹配多个a时
|| MatchCore(str + 1, pattern + 2) //当a*匹配一个a时
|| MatchCore(str, pattern + 2); //当a*.匹配a时
}
else {
return MatchCore(str, pattern + 2); //当b匹配a*时,把a*跳过
}
}
else {
if (*str == *pattern || (*pattern == '.' && *str != '\0')) { //若匹配当前字符
return MatchCore(str + 1, pattern + 1);
}
else {
return false;
}
}
}
bool match(const char *str, const char *pattern) {
if (str == nullptr || pattern == nullptr) { //输入空串不会return,因为空串并不是空指针
return false;
}
return MatchCore(str, pattern);
}
int main() {
if (match("d", "d*d*.")) {
cout << "匹配成功。" << endl;
}
else {
cout << "匹配失败。" << endl;
}
return 0;
}