正则表达式匹配

正则表达式匹配

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


动态规划解

设被匹配字符串为 s ,匹配字符串为 p 。利用一个二维数组 dp[][] 进行动态规划,dp[i][j] 表示 s 前 i 项与 p 前 j 项是否完成匹配。字符 ‘.’ 和任意单字符匹配,所以可以添加一个判定单字符是否匹配的函数,然后分匹配字符为 ‘*’ 还是普通字符讨论:

  1. p [ j - 1 ] == ’ * ’
    d p [ i ] [ j ] = { d p [ i − 1 ] [ j ]     u s e   ∗   t o   m a t c h d p [ i ] [ j − 2 ]                   n o t   u s e dp[i][j]= \left\{ \begin{aligned} dp[i-1][j]~~~use~*~to~match \\ dp[i][j-2] ~~~~~~~~~~~~~~~~~not~use \end{aligned} \right. dp[i][j]={dp[i1][j]   use  to matchdp[i][j2]                 not use
  2. p [ j - 1 ] 为 ’ . ’ 或普通字符
    d p [ i ] [ j ] = { d p [ i − 1 ] [ j − 1 ]    ( p [ j − 1 ]   m a t c h e s   s [ i − 1 ] ) f a l s e            ( n o t   m a t c h ) dp[i][j]= \left\{ \begin{aligned} dp[i-1][j-1]~~(p[j-1] ~matches~s[i-1])\\ false~~~~~~~~~~~(not~match) \end{aligned} \right. dp[i][j]={dp[i1][j1]  (p[j1] matches s[i1])false           not match
    注:dp[i][j] 中 i j 表示长度,转换为 s p 的索引时需要 -1

(补充)c++ 匿名函数

官方代码写了个匿名函数,正好复习一下匿名函数的写法:

基本格式:
[capture] [parameters] {body}

[capture] 可用的形式:
[]			//不截取任何变量,试图在Lambda内使用任何外部变量都是错误的(全局变量除外).
[&]			//截取外部作用域中所有变量,并作为引用在函数体中使用
[=] 		//截取外部作用域中所有变量,并拷贝一份在函数体中使用
[=, &foo]   //截取外部作用域中所有变量,并拷贝一份在函数体中使用,但是对foo变量使用引用
[bar]   	//截取bar变量并且拷贝一份在函数体重使用,同时不截取其他变量
[this]		//截取当前类中的this指针。如果已经使用了&或者=就默认添加此选项。

本题中需要截取变量 s p 引用,所以采用格式 [&]

完整代码

class Solution {
public:
    bool isMatch(string s, string p) {

        auto is_match = [&](int i,int j){
            if(i==0){
                return false;
            }
            if(p[j-1]=='.'){
                return true;
            }
            return s[i-1]==p[j-1];
        };

        int len_s=s.length();
        int len_p=p.length();
        vector<vector<int>> dp(len_s+1,vector<int>(len_p+1));
        dp[0][0]=1;
        for(int i=0;i<=len_s;++i){
            for(int j=1;j<=len_p;++j){
                if(p[j-1]=='*'){
                    dp[i][j] |= dp[i][j-2];
                    if(is_match(i,j-1)){
                        dp[i][j] |= dp[i-1][j];
                    }
                }else{
                    if(is_match(i,j)){
                        dp[i][j] |= dp[i-1][j-1];
                    }
                }
            }
        }
        return dp[len_s][len_p];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值