剑指offer学习笔记 正则表达式匹配

面试题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;
}
发布了193 篇原创文章 · 获赞 11 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/tus00000/article/details/104443368