剑指Offer19.正则表达式匹配 C++

1、题目描述

请实现一个函数用来匹配包含'. '和''的正则表达式。模式中的字符'.'表示任意一个字符,而' '表示它前面的字符可以出现任意次(含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abac a"匹配,但与"aa.a"和"aba"均不匹配。
示例 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 = "ca b"

输出: true

解释: 因为 '' 表示零个或多个,这里 'c' 为 0 个, 'a' 被重复一次。因此可以匹配字符串 "aab"。
示例 5 :
输入:
s = "mississippi"
p = "mis
isp ."

输出: false

2、VS2019上运行

krahets的方法--动态规划

cpp 复制代码
#include <iostream>
#include <string>
#include <vector>

using namespace std;

class Solution {
public:
    bool isMatch(string s, string p) {
        int m = s.size() + 1, n = p.size() + 1;
        vector<vector<bool>> dp(m, vector<bool>(n, false)); // 创建 DP 表格
        dp[0][0] = true; // 空字符串和空模式匹配成功
        for (int j = 2; j < n; j += 2) {
            // 初始化首行,当 p 的偶数位为 '*' 时,可以让 p 的奇数位出现 0 次,保持 p 是空字符串
            dp[0][j] = dp[0][j - 2] && p[j - 1] == '*';
        }
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                if (p[j - 1] == '*') { // 当前字符为星号
                    // 可以选择忽略星号和前一个字符,或者匹配前面的字符并继续匹配当前字符串
                    dp[i][j] = dp[i][j - 2] || (dp[i - 1][j] && (s[i - 1] == p[j - 2] || p[j - 2] == '.'));
                }
                else { // 当前字符为普通字符或者点号
                 // 前一个字符匹配成功,并且当前字符和模式字符相同或者模式字符是点号
                    dp[i][j] = dp[i - 1][j - 1] && (p[j - 1] == '.' || s[i - 1] == p[j - 1]);
                }
            }
        }
        return dp[m - 1][n - 1]; // 返回最终结果
    }
};

int main() {
    Solution solution;
    string s = "aab";
    string p = "c*a*b";
    bool result = solution.isMatch(s, p);
    cout << (result ? "匹配成功" : "匹配失败") << endl; // 输出匹配结果
    return 0;
}

匹配成功

3、解题思路

krahets

4、vector<vector> f(m + 1, vector(n + 1));

  • 创建了一个二维数组 f,用于保存匹配结果。f 的行数为 m + 1,列数为 n + 1,其中 m 是字符串 s 的长度,n 是正则表达式 p 的长度。
  • 初始时,将 f[0][0] 设置为 true,表示空字符串匹配为空字符串。
  • 这样做的原因是,当字符串和正则表达式都为空时,它们是匹配的,即空字符串可以匹配空字符串。
  • 通过将 f 数组初始化为全 false,除了首行首列设置为 true,我们可以利用动态规划的思想来计算不同子串之间的匹配关系。这样,f[i][j] 表示字符串 s 的前 i 个字符能否匹配正则表达式 p 的前 j 个字符。
相关推荐
YHY_13s28 分钟前
访问者模式
c++·访问者模式
我也不曾来过11 小时前
list底层原理
数据结构·c++·list
A charmer1 小时前
C++ 日志系统实战第三步:熟悉掌握各种设计模式
c++·日志系统
Ethon_王1 小时前
STL容器适配器详解:queue篇
c++
静听夜半雨1 小时前
CANoe入门——3、新建LIN工程及LIN DataBase(LDF文件)的创建
网络·数据库·c++·编辑器
梁下轻语的秋缘2 小时前
每日c/c++题 备战蓝桥杯 ([洛谷 P1226] 快速幂求模题解)
c++·算法·蓝桥杯
虾球xz2 小时前
游戏引擎学习第244天: 完成异步纹理下载
c++·学习·游戏引擎
矛取矛求2 小时前
C++区别于C语言的提升用法(万字总结)
c语言·c++
ephemerals__3 小时前
【c++11】c++11新特性(下)(可变参数模板、default和delete、容器新设定、包装器)
开发语言·c++
egoist20233 小时前
【C++指南】告别C字符串陷阱:如何实现封装string?
开发语言·数据结构·c++·c++11·string·auto·深/浅拷贝