【剑指offer】 面试题19 正则表达式匹配

面试题–【剑指Offer】 题目解答

题目要求

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

解题思路

根据输入,我们把只含有字符的串叫做字符串,把含有特殊匹配符号的串叫模式串
首先,我们考虑什么情况属于匹配成功?
1.字符串和模式串的对应位置元素相同,同时为空也算。
2.或者字符串为非空元素同时对应位置的模式串为’.’(即匹配任意非空字符)
然后匹配失败的情况有哪些呢?
当字符串为非空,模式串为空的时候,匹配失败。
需要注意的是,当字符串为空,模式串非空的时候,匹配不一定失败,因为模式串中星号元素可以匹配0个元素。如:“a*a*a*”

接着,我们就需要开始匹配字符了,每一个字符只有成功或者失败两个结果。
一个难点就是:当前位置字符串中对应模式串中的下一个字符是‘*’, 这里我们分两种情况讨论:模式串下一个字符为‘*’或不为‘*’:

为便于理解我们将字符串简写为str,将模式串简写为pattern。

1>pattern下一个字符不为‘*’:这种情况比较简单,直接匹配当前字符。如果
匹配成功,继续匹配下一个;如果匹配失败,直接返回false。注意这里的
“匹配成功”,除了两个字符相同的情况外,还有一种情况,就是pattern的
当前字符为‘.,同时str的当前字符不为‘\0’。(上文说的匹配两种情况)
当前元素匹配成功的话,字符串和模式串同时向后移动一个位置。

2>pattern下一个字符为‘*’时,稍微复杂一些,因为‘*’可以代表0个或多个。
这里把这些情况都考虑到:
	a>当‘*’匹配0个字符时,str当前字符不变,pattern当前字符后移两位,
跳过这个‘*’符号;
(解读:pattern不匹配当前str的字符,所以str不需要变,而pattern需要移动到*的下一个位置)
	b>当‘*’匹配1个或多个时,str当前字符移向下一个,pattern当前字符不变。
	(解读:这里匹配1个或多个可以看成一种情况,因为:当匹配一个时由于str移到了下一个字符,而pattern字符不变,就回到了上边的情况a,即下一次匹配0个字符。
	当匹配多于一个字符时即用一个*匹配多个字符,相当于从str的下一个字符继续开始匹配,str后移一位,pattern不变,)

主要代码c++

class Solution {
public:
    bool match(char* str, char* pattern)
    {
        if(str == nullptr || pattern == nullptr)
            return false;
        return matchCore(str, pattern);
    }
private:
    bool matchCore(char* str, char* pattern)
    {
        if(*str=='\0'&& *pattern=='\0')
            return true;
        if(*str!='\0'&& *pattern=='\0')
            return false;
        if(*(pattern+1) =='*') //模式串的下一个元素是*
        {
            if(*pattern==*str || (*pattern=='.'&&*str!='\0'))
                return matchCore(str,pattern+2)||matchCore(str+1,pattern);//匹配零个/一个或者多个
                //匹配0个字符(str,part+2)从下一位继续匹配(str+1,part),
            else
                return matchCore(str,pattern+2);//不匹配
        }
        //模式串的下一个元素不是*,那就直接判定是否匹配
        if(*str==*pattern || (*pattern=='.'&&*str!='\0'))
            return matchCore(str+1,pattern+1);
        else
            return false;
    }
};

总结

本题的难点在于理解清楚匹配和不匹配的情况,其中不要忽视字符串为空,模式串非空也可能匹配成功。另外就是在匹配的时候下一个元素是*的讨论,以及如何移动str和pattern(不匹配str=匹配0个 所以str不需要移动,匹配多个字符时,str动,pattern不需要移动),第一遍可能不太好理解,多熟悉几遍的话你就会发现其实并不是非常难的题目!加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值