LeetCode 10 正则表达式匹配

本文深入探讨了正则表达式匹配算法的基本思想及其实现细节,通过分析字符串S和模式字符串P的匹配过程,讲解了如何通过递归方法处理不同匹配场景,包括空字符串匹配、普通字符匹配、‘.’和‘*’特殊字符的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基本思想,逐个字符匹配,查看对应位置的字符是否相等,或者删除前一个字符后查看是否相等,或者重复前面字符(指的是上一个位置的字符,而不是所有前面的字符中的任意一个)若干次后查看是否相等。为了方便分析,首先我们要对两个字符串的类型进行分类,字符串S是指只包含字母的普通字符串,字符串P指的是包含‘.’和‘*’的模式字符串。这两个字符串出现的情形可以分为以下四种。

1)两个字符串都为空,那么不用匹配了,两者是完全相等的,返回true。

2)如果字符串S不为空,字符串P为空,则字符串P不可能去匹配S。那S为空,P不为空呢,这个时候是有可能去匹配的,因为P中的字符可以增加或减少(当然是在有字符‘*’的情况下),所以是有可能的。也就是说S不为空,P为空就返回false,其他情况再论。

3)我们注意到字符‘*’很重要,可以增加或删除字符,因此在匹配的过程中可以以P中下一个要匹配的字符是否是‘*’来分。这里首先讲不是‘*’的情况。判断对应位置字符是否相等,或者如果不相等时P中的字符是否是‘.’(别忘了‘.’可以表示任意一个字符),如果字符对应相等或者P中字符是’.‘,则进行下一位判断(递归,S和P同步进行下一步),否则返回false。

4)这种情况当然就是P中当前匹配的字符的下一个字符是’*‘了。和3)一样,判断对应位置字符是否相等,或者如果不相等时P中的字符是否是‘.’,如果字符对应相等或者P中字符是’.‘,(这个时候要直接同步进入到下一位吗,不行啊,既然P中的字符下一个是’*‘,则下一个位置对应位字符肯定不相等),此时就要看P中的’*‘匹配几个前面的字符了,如果匹配0个,也就是说把前面的那个字符(即当前的字符)删除,’*‘的已经做了他的工作了,则P中的字符要往前跳2位(例如S为aba,P为ab*ba),而S中的字符位置不变。如果匹配一个以上呢,也就说,P中的字符’*‘至少可以充当一个字符,即在*前可以添加一个字符,需要添加吗,不需要,因为我们比较的是字符,虚拟添加的那个字符和当前P中的字符是一样的,所以我们只需要把S中的字符往前前进一步,P中的位置保持不变(但是效果和真的添加后P中的字符往前一步一样,)开始下一步的匹配,有人说这有可能匹配很多个字符后S到末尾了,而P还是’*‘,别往了’*‘有删除作用啊,可以直接跳过’*‘。  好了,这是当前字符可以匹配的情况(例如S为abbba,P为abxa)。当前字符如果不匹配呢,那就简单了,直接用’*‘把P中当前字符前面那个和S中不一样的字符删除,也就是说,S位置保持不变,P跳两步(例如S为acab,P为abxcab)。有人说为什么没有S跳一步,P保持不变这种情形呢,当前已经不相等了,S中跳一步默认S当前的字符是可以匹配的,这是错误的。

代码如下:

class Solution {
public:
    bool isMatch(string s, string p) {
        
       return match(s,p,0,0);
    }
    bool match(string& s,string& p,int is,int ip)
    {
        if(is==s.size()&&ip==p.size()){
            return true;
        }else if(is!=s.size()&&ip==p.size()){
            return false;
        }else{
            if(ip+1==p.size()||p[ip+1]!='*'){
                if(is!=s.size()&&(s[is]==p[ip]||p[ip]=='.')){
                    return match(s,p,is+1,ip+1);
                }else{
                    return false;
                }
            }else {
                 if(is!=s.size()&&(s[is]==p[ip]||p[ip]=='.')){
                    return match(s,p,is,ip+2)|| match(s,p,is+1,ip);   
                }else{
                     return match(s,p,is,ip+2);
                 }
           }
       }
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值