4.21 leetcode -21 regular-expression-matching

来源:互联网 发布:单片机排针怎么用 编辑:程序博客网 时间:2024/05/17 15:03
题目描述

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


这题情况有点多,*是要搭配的,其余都是单体作战。比较麻烦的应该是这么一种情况
"abababababab",".*b","a.*";

最难的“ababxxxabab”,".*x.*";情况简直多。


这题需要动态规划来做,是我最不会的动态规划,专门搞了一个章节学习:

以下代码是看了牛客大神后改了一些的代码。

解释一下,新建了一个dp[n1+1][n2+1]的控件,其中dp[i+1][j+1]表示,s的0-i和p的0-j是否匹配

1:第一个for循环,是初始化,存在一种情况,s没有,但是p有很多x*,那么也是匹配的,所以全部得true一下。

     小瑕疵(dp[0][1]其实没有初始化)

2:就进入dp循环,分几种情况考虑

     1)首先假如碰到了'.'那么,他直接和斜对角那个值相等,也就是i和j各-1的值,假如是相等的,同理

     2 )其次,碰到了‘*’分来情况考虑,要是,j-1的数和i-1的数不等,说明这个*得孤独终老(算作无效),他的值也就和他的j-2一样,因为有他没他没差别;另一种情况,相等的,那就复杂了,首先,看j-2,没有他是不是true,没有他都是true,那么你存在着也肯定是true呀;再看,假如我起作用了,那么i-1,看看是否是true,假如那会儿我就能处理你,多你一个不多,继续是true(这里隐含了一个情况,就是i-1,j-2假如这个是true了,那么i-1,j肯定也是true,所以不用列进去,而牛客大神的dp[i+1][j],也就是j-1这因素,j-1假如ok,那么i-1,j-2也肯定ok,那么i-1,也肯定ok,那么就回到了我之前推导,所以我觉得不加可以)

class Solution {public:    bool isMatch(const char *s, const char *p) {        if(s == NULL || p == NULL)            return false;        int n1 = 0;        while(s[n1] != '\0')            n1++;        int n2 = 0;        while(p[n2] != '\0')            n2++;        bool** dp  = (bool **)malloc(sizeof(bool*)*(n1+1));//为二维数组分配,马丹,这里调了很久,不能一次性        for (int i = 0; i < (n1+1); ++i){            dp[i] = (bool*)malloc(sizeof(bool)*(n2+1));        }        dp[0][0]=true;        for (int i = 1; i < n2; i++)         {            if (p[i] == '*' && dp[0][i-1])             {                dp[0][i+1] = true;            }            else                dp[0][i+1] = false;    } for(int i = 0;i < n1;i++)            {            for(int j = 0;j < n2;j++)                {                if (p[j] == '.') {                    dp[i+1][j+1] = dp[i][j];                }                if (p[j] == s[i]) {                    dp[i+1][j+1] = dp[i][j];                }                 if (p[j] == '*' && j > 0) {                    if (p[j-1] != s[i] && p[j-1] != '.') {                        dp[i+1][j+1] = dp[i+1][j-1];                    } else {                        dp[i+1][j+1] = (dp[i][j+1] || dp[i+1][j-1]);//主要就是这部分的理解,牛客大神还有dp[i+1][j]                                                           //这部分,我觉得没有意义删掉了,从测试案例来说,没问题                    }                }         }        }        return dp[n1][n2];    }};