剑指Offer对答如流系列 - 正则表达式匹配

面试题19:正则表达式匹配

一、题目描述

请实现一个函数用来匹配包含'.''*'的正则表达式。

模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(含0次)。

在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但与"aa.a"及"ab*a"均不匹配。

二、问题分析

通过理解题意,发现 '.'的处理是最简单的。

关键是'*'的处理,分两种情况:
(1)当模式中的第二个字符不是“*”时:

  1. 如果字符串第一个字符和模式中的第一个字符相匹配,那么字符串和模式都后移一个字符,然后匹配剩余的。
  2. 如果字符串第一个字符和模式中的第一个字符相不匹配,直接返回false。

(2)当模式中的第二个字符是“*”时:有3种匹配方式:

  1. 模式后移2字符,相当于x*被忽略;
  2. 字符串后移1字符,模式后移2字符,x*相当于只匹配一个字符;
  3. 字符串后移1字符,模式不变,即继续匹配字符下一位,因为*可以匹配多位;

针对不同的场景,作出相应的处理即可。

三、问题解答

实现的易错点在 数组越界方面,写完代码后一定要好好检查一下。

public boolean match(char[] str, char[] pattern) {
        if (str == null || pattern == null) {
            return false;
        }
        return matchCore(str, 0, pattern, 0);
    }

    private boolean matchCore(char[] str, int indexOfStr, char[] pattern, int indexOfPattern) {

        if (indexOfStr == str.length && indexOfPattern == pattern.length) {
            return true;
        }

        if (indexOfStr < str.length && indexOfPattern == pattern.length){
            return false;
        }

        // 模式中的第二个字符是 * 时
        if (indexOfPattern + 1 < pattern.length && pattern[indexOfPattern + 1] == '*') {
            // 当前模式第一个字符能够成功匹配 
            if ( (indexOfStr < str.length && pattern[indexOfPattern] == '.')
                    || (indexOfStr < str.length && pattern[indexOfPattern] == str[indexOfStr])) {
                // 三种情况 
                // matchCore(str, indexOfStr, pattern, indexOfPattern + 2) 是考虑到aaa 与 aaa*a的情况
                return matchCore(str, indexOfStr, pattern, indexOfPattern + 2)
                        || matchCore(str, indexOfStr + 1, pattern, indexOfPattern)
                        || matchCore(str, indexOfStr + 1, pattern, indexOfPattern + 2);

            } else {
                // 不能匹配,则进行忽略 (X* 的*表示0)
                return matchCore(str, indexOfStr, pattern, indexOfPattern + 2);
            }
        }

        // 模式中的第二个字符不是 * 时
        if (indexOfStr < str.length && (pattern[indexOfPattern] == str[indexOfStr] || pattern[indexOfPattern] == '.')) {
            return matchCore(str, indexOfStr + 1, pattern, indexOfPattern + 1);
        }

        return false;
    }
发布了137 篇原创文章 · 获赞 3155 · 访问量 44万+

猜你喜欢

转载自blog.csdn.net/qq_42322103/article/details/104075463