正则表达式匹配

题目描述

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

思路

1、首先考虑字符串与模式串中有空串的情况:
a.当字符串和模式串都为空的时候,说明匹配完成,返回true。
b.当字符串不为空,模式串为空时,说明匹配失败,返回false。

2、当字符串为空,模式串不为空时,有匹配成功的可能,如a*a*。还有字符串和模式串都不为空时,需进一步讨论。因为星号的特殊性,所以我们以模式串当前位的下一位是否是星号分为两种情况:
a.模式串的下一位不是星号:判断字符串与模式串当前位是否相同,如果相同或者模式串当前位是‘.’且字符串当前位不是‘\0’时,则当前位匹配成功,字符串与模式串接着比较下一位;否则直接返回false。
b.模式串的下一位是星号:判断字符串与模式串当前位是否相同,如果相同或者模式串当前位是‘.’且字符串当前位不是‘\0’时,模式串该位可以选择匹配0次(模式串移动2位,字符串不动)或者选择匹配1次(模式串不动,字符串移动1位);如果字符串与模式串当前位不相同,模式串该位只能匹配0次,即模式串移动2位,字符串不动。

代码(c++)

class Solution {
public:
    bool match(char* str, char* pattern)
    {
        if(*str=='\0'&&*pattern=='\0') return true;
        if(*str!='\0'&&*pattern=='\0') return false;
        if(*(pattern+1)!='*'){
            if(*str==*pattern||(*pattern=='.'&&*str!='\0')){//'.'可以匹配除了'\0'之外的所有字符
                return match(str+1,pattern+1);
            }
            else return false;
        }
        else{
            if(*str==*pattern||(*pattern=='.'&&*str!='\0')){
                return match(str+1,pattern)||match(str,pattern+2);
            }
            else return match(str,pattern+2);
        }
    }
};

LeetCode 10.正则表达式匹配

这道题与上面的题是一样的,不同的是,如果用同样的代码,LeetCode某些测试用例会超时。因为上面的代码在递归时会重复查找。于是用动态规划的思路,用一个二维数组dp[i][j]存放已经判断过的以s[i],p[j]为首字母的匹配串和模式串是否匹配。过程如下
创建一个flag[s.length()+1][p.length()+1]大小的表格,用来记录以s[i],p[j]为首字母的匹配串和模式串是否匹配。从表格尾开始逐层像flag[0][0]移动。初始化所有元素为false。
1.一开始flag[s.length()][p.length()]=true,因为两个都为空时视为匹配。
在这里插入图片描述
2.对于其他元素,如果当前元素后一个元素不是*,就看此时模式串与匹配串对应字符是否匹配,以及其后的元素是否已经匹配flag[i+1][j+1];否则,当前模式串元素匹配0个flag[i][j+2]或1个flag[i+1][j])匹配串字符(此时模式串与匹配串对应字符匹配)。
在这里插入图片描述      ~~~~     在这里插入图片描述
3.对于最后一列元素(除了flag[s.length()][p.length()]),意味着模式串为空匹配串不为空,此时匹配失败,所以都是false。
4.最终flag[0][0]即为结果。
在这里插入图片描述

代码(c++)

class Solution {
public:
    bool isMatch(string s, string p) {
        bool** flag=new bool*[s.length()+1];
        for(int i=0;i<s.length()+1;i++){
            flag[i]=new bool[p.length()+1];
            for(int j=0;j<p.length();j++){
                flag[i][j]=false;
            }
        }
        flag[s.length()][p.length()]=true;
        for(int i=s.length();i>=0;i--){
            for(int j=p.length();j>=0;j--){
                if(i==s.length()&&j==p.length()) continue;
                else if(j==p.length()){
                    flag[i][j]=false;
                    continue;
                }
                bool firstelem=i<s.length()&&(s[i]==p[j]||p[j]=='.');
                if(p[j+1]!='*'){
                    flag[i][j]=firstelem&&flag[i+1][j+1];
                }
                else{
                    flag[i][j]=(firstelem&&flag[i+1][j])||flag[i][j+2];
                }
            }
        }
        return flag[0][0];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值