首页 > 其他分享 >LeetCode-10 正则表达式匹配

LeetCode-10 正则表达式匹配

时间:2024-01-02 11:37:20浏览次数:32  
标签:10 匹配 字符 正则表达式 零个 元素 字符串 LeetCode dp


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");
}


标签:10,匹配,字符,正则表达式,零个,元素,字符串,LeetCode,dp
From: https://blog.51cto.com/u_14189203/9065722

相关文章

  • LeetCode-22. 括号生成
    LeetCode-22.括号生成数字n代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且有效的括号组合。示例1:输入:n=3输出:["((()))","(()())","(())()","()(())","()()()"]示例2:输入:n=1输出:["()"]提示:1<=n<=8solution动态规划可以采用动态规划的思想,首......
  • LeetCode-23 合并 K 个升序链表
    LeetCode-23合并K个升序链表给你一个链表数组,每个链表都已经按升序排列。请你将所有链表合并到一个升序链表中,返回合并后的链表。示例1:输入:lists=[[1,4,5],[1,3,4],[2,6]]输出:[1,1,2,3,4,4,5,6]解释:链表数组如下:[1->4->5,1->3->4,2->6]将它们合并到一个有序链......
  • STM32F103C8T6移植RT_Thread nane过程记录
    一、创建基于官方库的裸机工程(这教程很多,每个人创建的工程风格也不一样,就不多赘述了) 二、下载RT-ThreadNano源代码(https://github.com/RT-Thread/rtthread-nano/archive/refs/heads/master.zip)  三、RT-ThreadNano源码目录结构 四、将核心文件添加到裸机工程中 ......
  • 2K1000开发板虚拟机 ubuntu 更换下载源
    Ubuntu系统软件的下载安装我们通常使用命令“apt-get”,该命令可以实现软件自动下载,安装,配置。该命令采用客户端/服务器的模式,我们的Ubuntu系统作为客户端,当需要下载软件的时候就向服务器发起请求,因此我们需要配置下服务器的地址,也就是更换ubuntu系统的下载源,首先打开......
  • 【LeetCode】46. 全排列
    一、题目描述给定一个不含重复数字的数组nums,返回其所有可能的全排列。你可以按任意顺序返回答案。示例1:输入:nums=[1,2,3]输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]示例2:输入:nums=[0,1]输出:[[0,1],[1,0]]示例3:输入:nums=[1]输出:[[1]]提示:1<=nums.......
  • 【LeetCode】2055. 蜡烛之间的盘子
    一、题目描述给你一个长桌子,桌子上盘子和蜡烛排成一列。给你一个下标从0开始的字符串s,它只包含字符'*'和'|',其中'*'表示一个盘子,'|'表示一支蜡烛。同时给你一个下标从0开始的二维整数数组queries,其中queries[i]=[lefti,righti]表示子字符串s[lefti...rig......
  • 【LeetCode】23. 合并K个升序链表
    一、题目描述给你一个链表数组,每个链表都已经按升序排列。请你将所有链表合并到一个升序链表中,返回合并后的链表。示例1:输入:lists=[[1,4,5],[1,3,4],[2,6]]输出:[1,1,2,3,4,4,5,6]解释:链表数组如下:[1->4->5,1->3->4,2->6]将它们合并到一个有序链表中得到。1->1->2......
  • 如何用 100 行 Shell 脚本实现一个 Docker?
    本文主要介绍使用shell实现一个简易的Docker。一、目的在初接触Docker的时候,我们必须要了解的几个概念就是Cgroup、Namespace、RootFs,如果本身对虚拟化的发展没有深入的了解,那么很难对这几个概念有深入的理解。本文的目的就是通过在操作系统中以交互式的方式去理解,Cgroup/Namesp......
  • #yyds干货盘点# LeetCode程序员面试金典:赎金信
    给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。如果可以,返回 true ;否则返回 false 。magazine 中的每个字符只能在 ransomNote 中使用一次。 示例1:输入:ransomNote="a",magazine="b"输出:false示例2:输入:ransomNot......
  • #yyds干货盘点# LeetCode程序员面试金典:按权重随机选择
    题目给你一个下标从0开始的正整数数组w,其中w[i]代表第i个下标的权重。请你实现一个函数pickIndex,它可以随机地从范围[0,w.length-1]内(含0和w.length-1)选出并返回一个下标。选取下标i的概率为w[i]/sum(w)。例如,对于w=[1,3],挑选下标0的概率......