正则表达式匹配

题目描述

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

递归

​ 如果是*的话,考虑将p串里这个*及前面的字母跳过去(匹配0个),或者在s串匹配一个里和*前面字母相同的字母(匹配1个)。就是暴力递归每次匹配0个或1个。

//递归
bool match(char* str, char* pattern)
{
    char *a=str;
    char *b=pattern;
    int lena=strlen(a);
    int lenb=strlen(b);
    if(lenb==0)return lena==0;
    bool flag=lena>0&&(b[0]=='.'||(a[0]==b[0]));
    if(lenb>1&&b[1]=='*'){
        return match(a,b+2)||(flag&&match(a+1,b));
    }else{
        return flag&&match(a+1,b+1);
    }
}

DP

class Solution {
public:
    bool isMatch(string s, string p) {
        s = " " + s;//防止该案例:""\n"c*"
        p = " " + p;
        //可以少一部分初始化
        int m = s.size(), n = p.size();
        bool dp[m + 1][n + 1];
        memset(dp, false, (m + 1) * (n + 1));
        dp[0][0] = true;//长度为0一定是匹配的
        for (int i = 1; i <= m; i++) {//枚举两个字符串的长度
            for (int j = 1; j <= n; j++) {//dp的意思是s长度为i,p长度为j是否匹配
                if (s[i - 1] == p[j - 1] || p[j - 1] == '.') {
                    //如果两个字符相等或者p是点就同时匹配两个
                    dp[i][j] = dp[i - 1][j - 1];
                } else if (p[j - 1] == '*') {
                    //如果是*
                    if (s[i - 1] != p[j - 2] && p[j - 2] != '.')
                        //二者不相等的时候,就将这个*和前面的字符都跳过去看是否匹配
                        dp[i][j] = dp[i][j - 2];
                    else {
                        //二者相等的时候,可以选择跳过或者选一个或多个
                        dp[i][j] = dp[i][j - 1] || dp[i][j - 2] || dp[i - 1][j];
                        // dp[i][j] = dp[i-1][j]  多个字符匹配的情况    
                        //or dp[i][j] = dp[i][j-1]  单个字符匹配的情况
                        //or dp[i][j] = dp[i][j-2]  没有匹配的情况    
                    }
                }
            }
        }
        return dp[m][n];
    }
};