[Leetcode] 10. Regular Expression Matching

题目

Implement regular expression matching with support for ‘.’ and ‘*’.

‘.’ Matches any single character.
‘*’ Matches zero or more of the preceding element.

The matching should cover the entire input string (not partial).

The function prototype should be:
bool isMatch(const char *s, const char *p)

Some examples:
isMatch(“aa”,”a”) ? false
isMatch(“aa”,”aa”) ? true
isMatch(“aaa”,”aa”) ? false
isMatch(“aa”, “a*”) ? true
isMatch(“aa”, “.*”) ? true
isMatch(“ab”, “.*”) ? true
isMatch(“aab”, “c*a*b”) ? true

字符串匹配,”.”任意一个字符,”*”0或者多个前一个字符

思路1 递归

情况如下:

  • 字符串p为空,若字符串s为空,则true 。
  • p[1] != “*”,若p[0] s[0]完全匹配,则判断p[1] s[1]是否匹配。
  • p[1] = “*”,1. 假设”*”符号数为0,判断p[2] s[0]是否匹配。2.假设”*”符号数不为0,且p[0] s[0]匹配,判断p[0] s[1]。
    bool isMatch(string s, string p) {
        if (p.size() == 0)
            return s.size() == 0;

        if (p.size() == 1 || p[1] != '*'){
            if (!s.empty() && (p[0] == s[0] || p[0] == '.')){
                return isMatch(s.substr(1), p.substr(1));
            }
            else{
                return false;
            }
        }
        //x*
        else{
            if(isMatch(s, p.substr(2))){
                return true;
            }
            else if (!s.empty() && (p[0] == s[0] || p[0] == '.')){
                return isMatch(s.substr(1), p);
            }
            else{
                return false;
            }
        }
    }

思路2 DP

建立1个二维数据记录是否匹配,传递真值。
dp[i][j]含义是字符串s[0:i] p[0:j]是否匹配。

值传递情况:

  • s[i] p[j]匹配,dp[i][j] = dp[i-1]][j-1]
  • p[j] = “*”,(1) p[j-1] s[i] 不匹配,dp[i][j] = dp[i][j-2]; (2) p[j-1] s[i]匹配,dp[i][j] = dp[i][j-2] || dp[i][j-1] || dp[i-1][j]
    传递dp[i][j-2]:*代表的字符数为0
    传递dp[i][j-1]:*代表的字符数为1
    传递dp[i-1][j]:*代表的字符数为 多个

dp二维数组 i,j=0,代表空串
对应s[i-1],p[j-1]才是字符串中的位置。

    bool isMatch_dp(string s, string p) {

        vector<vector<bool>> dp(s.size() + 1, vector<bool>(p.size() + 1, false));
        int rows = dp.size();
        int cols = dp[0].size();

        //空串为true
        dp[0][0] = true;

        //初始化第0列, p为空串
        for (int i = 1; i < rows; i++){
            dp[i][0] = false;
        }

        //初始化第0行, s为空串, 只有x*能匹配空串,如果有*,值与p[0][j-2]相同
        for (int j = 1; j < cols; j++){
            if (p[j-1] == '*' && j > 1){
                dp[0][j] = dp[0][j-2];
            }
        }

        for (int i = 1; i < rows; i++){
            for (int j = 1; j < cols; j++){
                //字符匹配,传递[i-1][j-1]值
                if (p[j-1] == s[i-1] || p[j-1] == '.'){
                    dp[i][j] = dp[i-1][j-1];
                }
                else if (p[j-1] == '*'){
                    if (p[j-2] == s[i-1] || p[j-2] == '.'){
                        dp[i][j] = dp[i][j-2] || dp[i][j-1] || dp[i-1][j];
                    }
                    else{
                        dp[i][j] = dp[i][j-2];
                    }
                }
            }
        }
        return dp[rows-1][cols-1];
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值