面试题.正则表达式匹配

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

示例 1:

输入: s = “aa” p = “a” 输出: false 解释: “a” 无法匹配 “aa” 整个字符串。

示例 2:

输入: s = “aa” p = “a*” 输出: true 解释: 因为 ‘*’ 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 ‘a’。因此,字符串 “aa” 可被视为 ‘a’ 重复了一次。

示例 3:

输入: s = “ab” p = “.” 输出: true 解释: “.” 表示可匹配零个或多个(’*’)任意字符(’.’)。

示例 4:

输入: s = “aab” p = “cab” 输出: true 解释: 因为 ‘*’ 表示零个或多个,这里 ‘c’ 为 0 个, ‘a’ 被重复一次。因此可以匹配字符串 “aab”。

示例 5:

输入: s = “mississippi” p = “misisp*.” 输出: false

s 可能为空,且只包含从 a-z 的小写字母。 p 可能为空,且只包含从 a-z 的小写字母以及字符 . 和 ,无连续的 ‘’。

注意:本题与主站 10 题相同:https://leetcode-cn.com/problems/regular-expression-matching/

解题思路

解题代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class Solution {
public:
    bool isMatch(string s, string p) {
        int n= s.size(),m = p.size();
        // if(n==0) return m==0;
        if(m==0) return n==0;
        //dp[i,j] = a[i]==b[i] && dp[i-1,j-1] || (dp[i-1,j]||dp[i,j-1])
        vector<vector<bool>> dp(n+1,vector<bool>(m+1));

        //构造p 的表达式
        dp[0][0] = true;
        for(int i=1;i<=m;i++) {
            if(p[i-1]=='*') dp[0][i] = dp[0][i-2];//****,表示任意字符
        }
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=m;j++) {
                char x = s[i-1];
                char y = p[j-1];
                if(x==y || y=='.' ) {
                    //匹配到 1
                    dp[i][j] = dp[i][j]|dp[i-1][j-1];
                }
                else if(y=='*' && j>=2 ) {
                    //匹配0  个字符
                    //* 依赖于前面的字符
                 
                    char prey = p[j-2];
                    dp[i][j] =dp[i][j] | dp[i][j-2];//匹配0个字符,当前* 无用
                    //匹配前一个字符
                    
                    // char prey = p[j-2];

                    if ( prey == x || prey == '.') 
                    //匹配前1个字符,prex is s[i-1]
                        dp[i][j] = dp[i][j]| dp[i-1][j];

                }

            }
        }
        return dp[n][m];

    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class Solution {
public:
    bool isMatch(string s, string p) {
        int n= s.size(),m = p.size();
        // if(n==0) return m==0;
        if(m==0) return n==0;
        //dp[i,j] = a[i]==b[i] && dp[i-1,j-1] || (dp[i-1,j]||dp[i,j-1])
        vector<vector<bool>> dp(n+1,vector<bool>(m+1));

        //构造p 的表达式
        dp[0][0] = true;
        for(int i=1;i<=m;i++) {
            if(p[i-1]=='*') dp[0][i] = dp[0][i-2];//****,表示任意字符
        }
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=m;j++) {
                char x = s[i-1],y = p[j-1];
                if( y == '*' && j>=2) {
                    //匹配0 个a ,例如 a*
                    dp[i][j] = dp[i][j-2];
                    if(  s[i-1] == p[j-1-1] || p[j-1-1] == '.') {
                        //匹配 1-n 个 a
                        dp[i][j] = dp[i][j] | dp[i-1][j];
                    }
                }else if (x== y || y == '.') {
                    dp[i][j] = dp[i-1][j-1];
                }
            }
        }
        return dp[n][m];
        




    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#define p pattern
class Solution {
public:
    
    bool match(string str, string pattern) {
        int n = str.size(),m = pattern.size();
        vector<vector<int>> dp(n+1,vector<int> (m+1));
        // . *[前面的字符出现0-n]
        dp[0][0] = 1;
        for(int i=1;i<=m;i++) dp[0][i] = dp[0][i-2] && pattern[i-1]=='*';
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=m;j++) {
                char x,y;
                x = str[i-1],y = pattern[j-1];
                if (x== y || y == '.' ) {
                    dp[i][j] = dp[i-1][j-1];
                } else if(y=='*' && y>=2) {
                    char prey = pattern[j-1-1];
                    if(prey == '.' || prey == x) {
                        dp[i][j] = dp[i][j-2];//匹配 0个,不匹配【*】没有用到
 
                        dp[i][j] |= dp[i-1][j];//匹配 n次, * 匹配 pre 或者 .
                        
                    }else {
                        dp[i][j] = dp[i][j-2];//匹配0个字符,不匹配
                    }
                }
                
            }
        }
        return dp[n][m];
    }
};