LeetCode-10 正则表达式匹配

2023-12-25 16:44:30

LeetCode-10 正则表达式匹配

给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.''*' 的正则表达式匹配。

  • '.' 匹配任意单个字符
  • '*' 匹配零个或多个前面的那一个元素

所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。

示例 1:

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

示例 2:

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

示例 3:

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

提示:

  • 1 <= s.length <= 20
  • 1 <= p.length <= 20
  • s 只包含从 a-z 的小写字母。
  • p 只包含从 a-z 的小写字母,以及字符 .*
  • 保证每次出现字符 * 时,前面都匹配到有效的字符

Solution

采用动态规划思想

建立dp[i][j]表示s的前i项与p 的前j项是否可以匹配

其中先初始化 dp 矩阵首行。dp[0][0] = true: 代表两个空字符串能够匹配。当p[i] == '*'dp[0][i] = dp[0][i - 2]

p[j]!=*

  • p[j]=='.',则此时无论如何s[i]都可以与p[j]匹配,所以此时dp[i][j]=dp[i-1][j-1]
  • 'a'<=p[j]<='z',则此时只有s[i]==p[j]时才可以匹配,所以此时dp[i][j]=dp[i-1][j-1]*(s[i]==p[j])

p[j]==*时,*表示匹配零个或多个前面的那一个元素

  • 若表示前一个元素为零个时,此时当且仅当dp[i][j]=dp[i][j-2]
  • 若表示前一个元素一或多个时且*前面为.时,此时dp[i][j]=dp[i-1][j]
  • 若表示前一个元素一或多个时且*前面不为.时,此时当且仅当p[j - 1] == s[i],即与*的前一个想匹配时,dp[i][j]=dp[i-1][j]
#include <string>
#include <cstring>
#include <iostream>

using namespace std;

//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
public:
    bool isMatch(string s, string p) {
        s = '0' + s;
        p = '0' + p;
        int dp[25][25];
        memset(dp, 0, sizeof(dp));
        dp[0][0] = 1;
        for (int i = 1; i < p.length(); ++i) {
            if (p[i] == '*') {
                dp[0][i] = dp[0][i - 2];
            }
        }
        // dp[i][j]对应s[:i+1],p[:j+1]是否匹配
        for (int i = 1; i < s.length(); ++i) {
            for (int j = 1; j < p.length(); ++j) {
                if (p[j] != '*') {
                    if (p[j] == '.') {
                        dp[i][j] = dp[i - 1][j - 1];
                    } else {
                        dp[i][j] = dp[i - 1][j - 1] * (s[i] == p[j]);
                    }
                } else {
                    // *前个字母匹配0次,其中p中j:*,j-1:_*,j-2:__*
                    //dp[i][j] = dp[i][j - 2];
                    // 因为*可以匹配多个所以是p[j - 1] == s[i]
                    //*前一个字母为.
                    //if (p[j - 1] == '.' && dp[i][j] == 0) {
                    //    dp[i][j] = dp[i - 1][j];
                    //}
                    //匹配*前一个字母
                    //if (p[j - 1] == s[i] && dp[i][j] == 0) {
                    //    dp[i][j] = dp[i - 1][j];
                    //}
                    dp[i][j] = (dp[i - 1][j] && (p[j - 1] == '.' || p[j - 1] == s[i])) || dp[i][j - 2];
                }
            }
        }
        cout << endl;
        cout << "  ";
        for (int i = 0; i < p.length(); ++i) {
            cout << p[i] << " ";
        }
        cout << endl;
        for (int i = 0; i < s.length(); ++i) {
            cout << s[i] << " ";
            for (int j = 0; j < p.length(); ++j) {
                cout << dp[i][j] << ' ';
            }
            cout << endl;
        }
        return dp[s.length() - 1][p.length() - 1];
    }
};
//leetcode submit region end(Prohibit modification and deletion)

int main() {
    Solution solution;
    solution.isMatch("aab", "c*a*b");
}

文章来源:https://blog.csdn.net/qq_43309286/article/details/135202005
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。