剑指 Offer -- 正则表达式匹配(五十二)

正则表达式匹配(五十二)

题目描述:

请实现一个函数用来匹配包括.*的正则表达式。模式中的字符.表示任意一个字符,而 *表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串”aaa”与模式”a.a”和”ab*ac*a”匹配,但是与”aa.a”和”ab*a”均不匹配.

代码(已在牛客上 AC)

这要题可以使用递归来做, 主要实现的方法是 matchCore(str, pattern);

match(str, pattern) 中:

  • 如果 strpattern 同时为空, 那么直接返回 false;

matchCore(str, pattern) 中:

  • 如果 strpattern 同时为 \0, 即都到了字符串的末尾, 说明二者完全匹配, 返回 true;
  • 如果 *str != '\0'pattern 先到结尾, 那么直接返回 false;
    后面的情况就是在 pattern 没有到结尾进行考虑的.

首先考虑 *(pattern + 1) 是否为 *:

  • 如果是的话, 那么就需要判断当前 *str*pattern 是否相等(同时要考虑 *pattern. 的情况, 由于其为 . 可以完全匹配一个字符, 因此需要保证此时 *str != '\0').

在上面条件满足的情况下, 要考虑以下三种情况:
1. * 匹配 0 个字符, 对应 matchCore(str, pattern + 2)
2. * 匹配 1 个字符, 对应 matchCore(str + 1, pattern + 2)
3. * 匹配多个字符, 对应 matchCore(str + 1, pattern)
而如果 *str*pattern 不相等, 由于 * 可以匹配 0 个字符, 所以可以继续进行匹配: matchCore(str, pattern + 2)

  • 如果 *(pattern + 1) 不等于 *, 那么只有 *str 与当前 *pattern 匹配才行.
  • 其他情况都返回 false.
class Solution {
public:
    bool match(char* str, char* pattern) {
        if (!str || !pattern) return false; // 指针为空, 返回 false;
        return matchCore(str, pattern);
    }
private:
    bool matchCore(char *str, char *pattern) {
        // 两者都到了各自的尾部, 返回 true
        if (*str == '\0' && *pattern == '\0') return true;
        // 如果字符串没有到尾部, 但是模式串到了结尾, 那么就返回 false;
        // 但是如果字符串到了尾部, 而模式串没有到尾部的话, 还要继续判断, 因为
        // 模式串结尾可能是 '*'.
        if (*str != '\0' && *pattern == '\0') return false;
        // 如果模式串下一个字符是 '*'
        // 那么根据当前的字符 str[i] 与 pattern[j] 是否相等分为两种情况讨论:
        if (*(pattern + 1) == '*') {
            if (*str == *pattern || (*str != '\0' && *pattern == '.')) {
                // 如果 str[i] 与 pattern[j] 相等, 那么由于pattern[j+1]=='*', 需要考虑三种情况:
                // 1. '*' 匹配 0 个字符;
                // 2. '*' 匹配 1 个字符
                // 3. '*' 匹配多个字符
                return matchCore(str, pattern + 2) || // 情形 1
                    matchCore(str + 1, pattern + 2) || // 情形 2
                    matchCore(str + 1, pattern); // 情形 3
            }
            // 如果 str[i] 与 pattern[j] 不相等, 那么由于 pattern[j+1]=='*',
            // 就可以跳过 '*' 继续判断.
            else
                return matchCore(str, pattern + 2);
        }
        // 针对 pattern[j + 1] != '*' 的情况, 有以下两个的特殊情况, 如果:
        // 1. *str 与 *pattern 相等
        // 2. *str 不为 '\0' 时并且 *pattern == '.'
        if (*str == *pattern || (*str != '\0' && *pattern == '.'))
            return matchCore(str + 1, pattern + 1);
        // 其余的情况, 直接返回 false
        return false;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值