剑指offer-正则表达式匹配

36 篇文章 0 订阅
8 篇文章 0 订阅

正则表达式匹配

题目描述

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

问题分析

下面是匹配结束情形:

  1. str到尾,pattern到尾,匹配成功

    if (strIndex == str.length && patternIndex == pattern.length) {
            return true;
        }
  2. str未到尾,pattern到尾,匹配失败

    if (strIndex != str.length && patternIndex == pattern.length) {
            return false;
    }
  3. str到尾,pattern未到尾(不一定匹配失败,因为a*可以匹配0个字符)

    if (strIndex == str.length && patternIndex != pattern.length) {
            //只有pattern剩下的部分类似a*b*c*的形式,才匹配成功
            //  递归匹配
            if (patternIndex + 1 < pattern.length && pattern[patternIndex + 1] == '*') {
                return matchCore(str, strIndex, pattern, patternIndex + 2);
            }
            return false;
    }
  4. str未到尾,pattern未到尾,且模式串后一个字符为*,

    if (patternIndex + 1 < pattern.length && pattern[patternIndex + 1] == '*') {
            if (pattern[patternIndex] == str[strIndex] || (pattern[patternIndex] == '.' && strIndex != str.length)) {
                return matchCore(str, strIndex, pattern, patternIndex + 2)//*匹配0个,跳过
                        || matchCore(str, strIndex + 1, pattern, patternIndex + 2)//*匹配1个,跳过
                        || matchCore(str, strIndex + 1, pattern, patternIndex);//*匹配1个,再匹配str中的下一个
            } else {
                //直接跳过*(*匹配到0个)
                return matchCore(str, strIndex, pattern, patternIndex + 2);
            }
        }
  5. 当前匹配成功,但是模式下一个元素不是*

    if (pattern[patternIndex] == str[strIndex] || (pattern[patternIndex] == '.' && strIndex != str.length)) {
            return matchCore(str, strIndex + 1, pattern, patternIndex + 1);
        }
  6. 其他匹配失败,返回失败
    return false;

由于涉及子串的比较,递归无疑是最好的办法,完整代码为:

package com.genge.offer;

/**
 * Created by Genge on 2016-07-07.
 *
 * 正则表达式匹配
 */
public class Match {
    /**
     * 请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,
     * 而'*'表示它前面的字符可以出现任意次(包含0次)。
     * 在本题中,匹配是指字符串的所有字符匹配整个模式。
     * 例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配
     * @param str
     * @param pattern
     * @return
     */
    public boolean match(char[] str, char[] pattern) {
        if (str == null || pattern == null) {
            return false;
        }
        int strIndex = 0;
        int patternIndex = 0;
        return matchCore(str, strIndex, pattern, patternIndex);
    }

    public boolean matchCore(char[] str, int strIndex, char[] pattern, int patternIndex) {
        //str到尾,pattern到尾,匹配成功
        if (strIndex == str.length && patternIndex == pattern.length) {
            return true;
        }
        //str未到尾,pattern到尾,匹配失败
        if (strIndex != str.length && patternIndex == pattern.length) {
            return false;
        }
        //str到尾,pattern未到尾(不一定匹配失败,因为a*可以匹配0个字符)
        if (strIndex == str.length && patternIndex != pattern.length) {
            //只有pattern剩下的部分类似a*b*c*的形式,才匹配成功
            if (patternIndex + 1 < pattern.length && pattern[patternIndex + 1] == '*') {
                return matchCore(str, strIndex, pattern, patternIndex + 2);
            }
            return false;
        }

        //str未到尾,pattern未到尾
        if (patternIndex + 1 < pattern.length && pattern[patternIndex + 1] == '*') {
            if (pattern[patternIndex] == str[strIndex] || (pattern[patternIndex] == '.' && strIndex != str.length)) {
                return matchCore(str, strIndex, pattern, patternIndex + 2)//*匹配0个,跳过
                        || matchCore(str, strIndex + 1, pattern, patternIndex + 2)//*匹配1个,跳过
                        || matchCore(str, strIndex + 1, pattern, patternIndex);//*匹配1个,再匹配str中的下一个
            } else {
                //直接跳过*(*匹配到0个)
                return matchCore(str, strIndex, pattern, patternIndex + 2);
            }
        }

        if (pattern[patternIndex] == str[strIndex] || (pattern[patternIndex] == '.' && strIndex != str.length)) {
            return matchCore(str, strIndex + 1, pattern, patternIndex + 1);
        }

        return false;
    }
}

此题要求逻辑清晰,对各种情形进行分类处理,不多也不能少

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值