剑指 Offer 19. 正则表达式匹配(难度:困难)

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

示例 1: 输入: s = “aa” p = “a” 输出: false 解释: “a” 无法匹配 “aa” 整个字符串。

示例 2: 输入: s = “aa” p = “a*” 输出: true 解释: 因为 ‘*’ 代表可以匹配零个或多个前面的那一个元素,
在这里前面的元素就是 ‘a’。因此,字符串 “aa” 可被视为 ‘a’ 重复了一次。

示例 3: 输入: s = “ab” p = “." 输出: true 解释: ".
表示可匹配零个或多个(’*’)任意字符(’.’)。

示例 4: 输入: s = “aab” p = “cab” 输出: true 解释: 因为 ‘*’ 表示零个或多个,这里 ‘c’ 为 0
个, ‘a’ 被重复一次。因此可以匹配字符串 “aab”。

示例 5: 输入: s = “mississippi” p = “misisp*.” 输出: false s 可能为空,且只包含从
a-z 的小写字母。 p 可能为空,且只包含从 a-z 的小写字母以及字符 . 和 ,无连续的 '’。

题解:

这种匹配思路其实就是不断地减掉s和p的可以匹配首部,直至一个或两个字符串被减为空的时候,根据最终情况来得出结论。

如果只是两个普通字符串进行匹配,按序遍历比较即可:

if( s.charAt(i) == p.charAt(i) ) 如果正则表达式字符串p只有一种"."一种特殊标记,依然是按序遍历比较即可:

if( s.charAt(i) == p.charAt(i) || p.charAt(i) == ‘.’ )
上述两种情况实现时还需要判断字符串长度和字符串判空的操作。

但是,"*"这个特殊字符需要特殊处理,当p的第i个元素的下一个元素是星号 时会有两种情况:

i元素需要出现0次,我们就保持s不变,将p的减掉两个元素,调用isMatch。例如s:bc、p:abc,我们就保持s不变,减掉p的"a",调用isMatch(s:bc,p:bc)。

i元素需要出现一次或更多次,先比较i元素和s首元素,相等则保持p不变,s减掉首元素,调用isMatch。例如s:aabb、p:abb,就保持p不变,减掉s的首元素,调用isMatch(s:abb,p:abb)。
此时存在一些需要思考的情况,例如s:abb、p:a*abb,会用两种方式处理:

按照上述第二种情况比较i元素和s首元素,发现相等就会减掉s的首字符,调用isMatch(s:bb,p:a*abb)。在按照上述第一种情况减去p的两个元素,调用isMatch(s:bb,p:abb),最终导致false。

直接按照上述第一种情况减去p的两个元素,调用isMatch(s:abb,p:abb),最终导致true。
所以说这算是一种暴力方法,会将所有的情况走一遍,看看是否存在可以匹配的情况。

class Solution {
    public boolean isMatch(String s, String p) {
        //如果正则串p为空字符串s也为空这匹配成功,如果正则串p为空但是s不是空则说明匹配失败
        if (p.isEmpty())return s.isEmpty();
        //判断s和p的首字符是否匹配,注意要先判断s不为空
        boolean headMatched=!s.isEmpty()&&(s.charAt(0)==p.charAt(0)||p.charAt(0)=='.');
        if (p.length()>=2&&p.charAt(1)=='*'){//如果p的第一个元素的下一个元素是*
            //则分别对两种情况进行判断
            return isMatch(s,p.substring(2))||
                (headMatched&&isMatch(s.substring(1),p));
        }else if (headMatched){//否则,如果s和p的首字符相等
            return isMatch(s.substring(1),p.substring(1));
        }else {
            return false;
        }
    } }

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zheng-ze-biao-da-shi-pi-pei-lcof

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小码1号

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值