算法:字符串正则匹配

算法之正则表达式:强大的字符串模式匹配工具 在算法的学习过程中,我始终坚信分享能让知识的传播更广泛,交流能让我们对知识的理解更深刻。正则表达式作为一种在字符串处理中极为强大的工具,在众多领域都有着广泛的应用。今天,我就想把自己在学习正则表达式相关知识时的收获分享给大家,咱们一起学习进步,探索它的奥秘。 阅读详情

dp解法,时间复杂度O(NNM),空间复杂度O(N*M)
dp[i][j] 表示 str[i…La] 和 pattern[j…Lb] 是否通配

动态规划,从后向前推
第一,dp[La][Lb]一定为真,两个空串
第二,处理dp[i][Lb]部分,表示pattern已经结束,str没有结束,所以全部为假
第三,处理dp[La][j]部分,表示str已经结束,pattern没有结束,所以当pattern结尾都是X* 才会为真
第四,处理dp[i][Lb-1]部分,由于* 的存在,所以此部分需要特殊处理,表示pattern只剩最后一个字符,str没有结束,只有dp[La][Lb]有可能为真,其他都为假。
第五,打表dp[i][j],其中当pattern[j]==’*’,所有dp[i][j]为假,dp[i][j] 只依赖 dp[i+1][j+1] 或 dp[i+k(k>=0)][j+2]的值。


简洁代码:

class Solution {
public:
    bool match(char* str, char* pattern)
    {
        int La = strlen(str);
        int Lb = strlen(pattern);
        if(La == 0 && Lb == 0) return true;
        if(Lb == 0) return false;
        bool dp[La+1][Lb+1];
        memset(dp,0,sizeof(dp));
        dp[La][Lb] = true;
        for(int j = Lb -2 ; j>=0; j-=2){
            if(pattern[j+1] == '*' && pattern[j] != '*'){
                dp[La][j] = true;
            }else{
                break;
            }
        }
        if(str[La-1] == pattern[Lb-1] || pattern[Lb-1]=='.')
            dp[La-1][Lb-1] = true;
        for(int i=La-1;i>=0;i--){
            for(int j=Lb-2;j>=0;j--){
                if(pattern[j+1] == '*'){
                    int k = i;
                    while(k<La && 
                          (pattern[j] == str[k] || pattern[j] == '.')){
                        if(dp[k][j+2]){
                            dp[i][j] = true;
                            break;
                        }
                        k++;
                    }
                    dp[i][j] = dp[i][j] || dp[k][j+2];
                }else{
                    dp[i][j] = dp[i+1][j+1] && 
                        (pattern[j] == str[i] || pattern[j] == '.');
                }
            }
        }
        return dp[0][0];
    }
};

带注释代码

class Solution {
public:
    bool match(char* str, char* pattern)
    {
        int La = strlen(str);
        int Lb = strlen(pattern);
        if(La == 0 && Lb == 0) return true;
        if(Lb == 0) return false;
        
        //动态规划,从后向前推
        bool dp[La+1][Lb+1];
        memset(dp,0,sizeof(dp));
        // 第一,dp[La][Lb]一定为真,两个空串
        dp[La][Lb] = true;
        // 第二,处理dp[i][Lb]部分;
        // 表示pattern已经结束,str没有结束,所以全部为0
        
        // 第三,处理dp[La][j]部分
        // 表示str已经结束,pattern没有结束,所以当pattern结尾都是X*才会为真
        for(int j = Lb -2 ; j>=0; j-=2){
            if(pattern[j+1] == '*' && pattern[j] != '*'){
                dp[La][j] = true;
            }else{
                break;
            }
        }
        
        // 第四,处理dp[i][Lb-1]部分,由于*的存在,所以此部分需要特殊处理
        // 表示pattern只剩最后一个字符,str没有结束
        // 只有dp[La][Lb]有可能为真,其他都为假。
        if(str[La-1] == pattern[Lb-1] || pattern[Lb-1]=='.')
            dp[La-1][Lb-1] = true;
        
        // 第五,打表dp[i][j],其中当pattern[j]=='*',所有dp[i][j]为假
        // dp[i][j] 只依赖 dp[i+1][j+1] 和 dp[i+k(k>=0)][j+2]的值。
        for(int i=La-1;i>=0;i--){
            for(int j=Lb-2;j>=0;j--){
                if(pattern[j+1] == '*'){
                    int k = i;
                    // 只有当 str[k] 和 pattern[j] 通配时
                    // dp[i][j] 才依赖 dp[k][j+2]
                    while(k<La && 
                          (pattern[j] == str[k] || pattern[j] == '.')){
                        if(dp[k][j+2]){
                            dp[i][j] = true;
                            break;
                        }
                        k++;
                    }
                    // 可能通配到最后
                    dp[i][j] = dp[i][j] || dp[k][j+2];
                }else{
                    dp[i][j] = dp[i+1][j+1] && 
                        (pattern[j] == str[i] || pattern[j] == '.');
                }
            }
        }
        return dp[0][0];
    }
};
【动态规划】【字符串】C++算法:10正则表达式匹配 给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。 '.' 匹配任意单个字符 '*' 匹配零个或多个前面的那一个元素 所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。 阅读详情

相关推荐

5G初始注册流程详解(2)-Registration Request

1:了解注册的本质,5G终端为什么要注册? 2:SUCI,SUPI,5G-GUTI的区别? 3:为什么会有COMPLETE REGISTRATION REQUEST呢?

weixin_53220301的博客 3795

正则匹配之正则匹配全部汇总:

实用的正则匹配大全,有需要可以进来看看哈

Remix_xy的博客 3万+

EMQX 结合MySQL实现精细化ACL权限管理实战

本文详细介绍了如何通过EMQX结合MySQL实现精细化的ACL权限管理,提升物联网设备接入和消息传输的安全性。内容包括环境准备、基础配置、权限规则设计技巧以及高级应用与性能优化方案,帮助开发者快速掌握动态生效、便于管理的权限控制方法。

weixin_28683689的博客 198

正则表达式匹配算法详解(由ChatGPT-3.5生成)

正则表达式匹配算法是一个经典的算法问题,通过使用动态规划的方法,我们可以高效地解决这个问题。在实现过程中,我们可以进行一些优化,包括空间复杂度的优化。希望本篇博客对读者理解正则表达式匹配算法有所帮助。如果你有任何疑问或者其他方面的优化,请随时提出。以上是关于正则表达式匹配算法的详细介绍。通过使用动态规划的思想,结合对状态转移的分析,我们能够高效地解决这个问题。同时,通过对空间复杂度的优化,我们能够进一步提升算法的效率。希望这篇博客能够帮助读者更好地理解和掌握正则表达式匹配算法。

感谢关注 848

Android 13高通平台CTS camera部分fail项修改(续)

接着上一篇,有几个提了case高通也分析了很久的fail项,其中最离谱的是问题1,第一个接手case的人反反复复处理、内部排查踢皮球、要求log,折腾了很久,最终就给出个解不了的结论。后面还是靠着自己发现了一些蛛丝马迹,并且换了个case接手人才最终解决。

hkj887tg的博客 2061

java写一个多人线上聊天室

课程作业谔谔

weixin_51614848的博客 1136

字符串之正则表达式匹配

1.本题知识点    字符串、递归 2. 题目描述   请实现一个函数用来匹配包括 . 和 * 的正则表达式。模式中的字符 . 表示任意一个字符,而 * 表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配。 3. 思路    这题对编程来说没多大难度,...

守得云开见月明 1万+

生态学家都在用的MixSIAR:用R语言搞定稳定同位素混合模型(从数据整理到结果解读)

本文详细介绍了生态学家常用的MixSIAR工具,通过R语言实现稳定同位素混合模型分析,从数据整理到结果解读全流程。文章涵盖环境准备、模型构建、参数设置、运行诊断及可视化等关键步骤,帮助研究者科学分析河口鱼类食物来源,适用于生态学研究和湿地保护政策制定。

weixin_28683065的博客 440

详解正则表达式匹配算法原理

正则表达式的匹配算法,是怎么实现的呢?

ybdesire的专栏 2万+

iOS面试题大全(附带答案)

C语言相关面试题 1.static有什么用途? 答案:在C语言中,static主要定义全局静态变量,定义局部静态变量,定义静态函数。 static 属于静态变量,使用它修饰的变量生命周期是整个源程序。 @1.在函数体内的 static 变量的作用范围为该函数体,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值; @2.在模块内的 static 全局变量可以被模块内所有函数访问,但不能被模块外其它函数访问; @3.在模块内的 static 函数只被这一模块内的其它函数调用,这个函数的使用范围被限

IOSNF的博客 2427

【Linux内核】Linux内核裁剪完全指南:从理论到实战的系统优化

在嵌入式设备、专用服务器和物联网系统日益普及的今天,如何让Linux系统在资源受限的环境中高效运行成为开发者必须面对的问题。Linux内核裁剪正是解决这一问题的关键技术,它通过移除不必要的内核组件,打造出更精简、更安全、更高效的自定义操作系统。本文将系统全面地介绍Linux内核裁剪的完整流程和实用技巧,帮助您掌握这一核心技能。Linux内核裁剪是一项结合技术知识与实践经验的系统工程。明确需求:裁剪前必须清晰了解目标系统的硬件配置和功能需求。循序渐进:采取小步修改、反复测试的策略,避免一次性大幅修改。

撬动未来的支点的专栏 1391

算法学习篇3——正则表达式

正则表达式是文本处理中不可或缺的工具,理解其底层算法有助于编写更高效、更准确的正则表达式。未来随着正则表达式引擎的不断优化,以及与其他文本处理技术(如自然语言处理)的结合,正则表达式将继续在数据处理领域发挥重要作用。

a19884792066的博客 822

hadoop 切片机制详解

hadoop切片机制详解

congge 1万+

问题记录:一个简单的字符串正则匹配算法引发的 CPU 告警

正则表达式因使用回溯算法(NFA)在匹配复杂URL时可能导致CPU使用率飙升,尤其在高频调用或海量数据场景下。优化建议包括预编译Pattern、优化正则结构(避免贪婪匹配)、避免循环中重复创建Matcher、分层匹配以及使用高性能替代方案(如java.net.URL或RE2/J引擎)。定位问题可通过分析CPU栈中的正则回溯方法,最终根据场景选择预编译、标准库解析或RE2引擎等方案以提升性能。

技术研究记录 594

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

剑指 offer 字符串算法题:正则表达匹配

模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(含0次)。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但与"aa.a"和"ab*a"均不匹配。3. 模式字符串前两个不是字符 x + *时,由模式字符串中首个字符与字符串中的首个字符是否匹配(即该模式字符为 . 或者两字符相等)且字符串除首个字符以外的后续字串与模式字符串除首个字符以外的模式是否匹配决定;由于匹配是指字符串的所有字符匹配整个模式,所以正则表达式应该将模式串使用 ^ $来限制即可。

薛定谔的猫-前端领域 273

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

来自一道算法题:正则表达式之匹配字符串中连续重复的字符(JavaScript描述)

最近在做遇到如下的算法题: 其实这算不上什么算法题,纯属是对正则表达式的应用,在这里我们用JavaScript语法进行实现。在实现之前还是先回顾一下知识点吧,在知道的基础看看能不能写出来! 正则表达式的两个方法 (1)RegExp.prototype.test(str) 用于测试字符串参数中是否存在匹配正则表达式模式的字符串,如果存在则返回true,否则返回false。 (2)RegE...

一起的远方的博客 3883

算法题解(LeetCode 6-10:Z 字形变换、整数反转、字符串转换整数(atoi)、 回文数、正则表达式匹配)

文章目录[6. Z 字形变换 9/2](https://leetcode-cn.com/problems/zigzag-conversion/)[7. 整数反转 9/3](https://leetcode-cn.com/problems/reverse-integer/) 6. Z 字形变换 9/2 将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。 比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下: P A H N A

x-dragon8899的博客 334

C++ 正则文法定义与字符串匹配算法资源包:让编译原理学习更简单

C++ 正则文法定义与字符串匹配算法资源包:让编译原理学习更简单 去发现同类优质开源项目:https://gitcode.com/ 项目核心功能/场景 C++ 正则文法定义与字符串匹配算法资源包,提供正则文法自定义、NFA构建、DFA转换与最小化及字符串匹配功能。 项目介绍 在计算机科学和编译原理领域,正则表达式及其对应自动机的实现是基础且重要的内容。C++ 正则文法定义与字符串匹配算法资源包应运...

gitblog_06767的博客 680

OpenSnitch规则匹配算法终极指南:从简单字符串到复杂正则表达式的完整解析

OpenSnitch是一款受Little Snitch启发的GNU/Linux交互式应用防火墙,它通过强大的规则匹配系统让用户精确控制应用程序的网络访问权限。本文将深入解析OpenSnitch的规则匹配算法,从基础的字符串匹配到高级的正则表达式,帮助你掌握构建安全策略的核心技能。 ## 规则匹配的核心架构 OpenSnitch的规则系统基于**操作符(Operator)** 和**规则(Rul

gitblog_00173的博客 472

动态规划算法-两个数组的dp(含字符串数组):45.正则表达式匹配

动态规划算法-两个数组的dp(含字符串数组):45.正则表达式匹配解析

要努力去发光,而不是被照亮~ 369

C++复习之路:算法与数据结构相关14:字符串的正则表达式匹配,做牛客上的剑指offer遇到的简单的基础知识(4):

例题: 请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前一个的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ab*a"匹配,但是与"aa.a"和"ab*a"均不匹配。 方法1:递归 思路: 假设主串为s,长度为sn, 模式串为p,长度为pn,对于模式串p当前的第i位来说,有'正常字符'、'*'、'.'三种情况。我们针对这三种情况进行讨论: 如果p[.

weixin_42067304的博客 162

正则表达式匹配

题目描述: 给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘*’ 的正则表达式匹配。 ‘.’ 匹配任意单个字符 ‘*’ 匹配零个或多个前面的那一个元素 所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。 方法一:回溯法 这种匹配思路其实就是不断地减掉s和p的可以匹配首部,直至一个或两个字符串被减为空的时候,根据最终情况来得出结论。 class Solution {...

qq_42174669的博客 194

剑指 正则表达式匹配

题目描述 请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配。 这道题主要是把思路捋清楚了就Ok.用指针来实现,能匹配上,指针就后移; 分成两...

keliwahada 243

字符串 6. 重复的子字符串(正则式、移动匹配、KMP)

给定一个字串s,如果它由重复子串构成,那么它循环右移最多n/2次(两个循环节的情况)即可回到原本的s。(具体证明可以看代码随想录,不过感觉这里代码随想录的证明写的八太行,我直接看过一遍后放弃看懂,不如直接记住定理)s1 = s+s,将s1的头尾字符去除,然后判断s1中是否能找到s,如果可以,则字串s由重复子串构成。正则表达式的功能确实很强大,但是有一个缺点,就是程序解析正则式需要的时间比较多,耗时较大。最近修的NLP课学了正则表达式,那就小用一波正则表达式秒了(学以致用,有爽到)。KMP学不会啊学不会。

m0_49844155的博客 1242

JAVA程序设计:正则表达式匹配(LeetCode:10)

给你一个字符串s和一个字符规律p,请你来实现一个支持 '.'和'*'的正则表达式匹配。 '.' 匹配任意单个字符 '*' 匹配零个或多个前面的那一个元素 所谓匹配,是要涵盖整个字符串s的,而不是部分字符串。 说明: s可能为空,且只包含从a-z的小写字母。 p可能为空,且只包含从a-z的小写字母,以及字符.和*。 示例 1: 输入: s = "aa" p...

信仰.的博客 671

牛客网 字符串匹配(STL或暴力匹配)

牛客网 字符串匹配(STL或暴力匹配)

Pure_vv的博客 791
上一篇: 算法:数组上二分问题
下一篇: 算法:单向链表相交
ShellDawn
博客等级 码龄10年 75粉丝 756原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值