字符串模式匹配,经典KMP算法你还不会?我可不允许你不会!
文章目录
- 重点
- 1. 简单模式匹配算法
- 2. 部分匹配值PM的算法(Move = j-1 + PM[j-1])
- 3. 部分匹配值PM的两次改进(Move = j-next[j])
- 4. 快速得到next数组
- 5. KMP匹配算法
重点
童鞋们看网上讲解的时候一定要分清楚序列是从0开始还是从1开始,有些博主就是纯纯的转载文章,没有任何修改,把一篇错误的文章转来转去,误导了同学们。
所以我在这里提醒同学们一定要注意序列下标从什么开始的。
我的算法是根据王道考研总结出来的,并且主串、模式、next的下标都是从1开始的
1. 简单模式匹配算法

int search(String txt, String part){for(int i=0; i<txt.length-part.length; ++i){for(int j=0; j<M; j++){if(part[j] != txt[i+j]) break;}if(j == M) return i;}return -1;
}
2. 部分匹配值PM的算法(Move = j-1 + PM[j-1])
1. 部分匹配值PM
模式(a b c a c)
‘a’的前缀为空,后缀为空,两者交集为空;
‘ab’的前缀为{a},后缀为{b},两者交集为空;
‘abc’的前缀为{a,ab},后缀为{bc,c},两者交集为空;
'abca’的前缀为{a,ab,abc},后缀{bca,ca,a},两者交集为{a};
‘abcac’的前缀为{a,ab,abc,abca},后缀{bcac,cac,ac,c},两者交集为空
2. 利用上述得到的部分匹配值PM完成匹配
【第一趟匹配过程】
发现a与c不匹配,前两个字符是匹配的,查表可知,最后一个匹配字符b对应的部分匹配值为0,因此:移动位数=已匹配的字符数 - 对应的部分匹配值=2-0=2,所以将子串向后移动2位。j=1+PM
【第二趟匹配过程】
发现b与c不匹配,前四个字符是匹配的,查表可知,最后一个匹配字符a对应的部分匹配值为1,因此:移动位数=已匹配的字符数 - 对应的部分匹配值=4-1=3,所以将子串向后移动3位。j=1+PM
【第三趟匹配过程】
成功
3. 具体实例

3. 部分匹配值PM的两次改进(Move = j-next[j])
已知:右移位数=已匹配的字符数 - 对应的部分匹配值,即为Move=(j-1)- PM[j-1];
使用部分匹配值时,每当匹配失败,就去找它前一个元素的部分匹配值,这样使用起来有些不方便,所以将PM表右移一位,这样哪个元素匹配失败,直接看它自己的部分匹配值即可。

有时候为了让公式变得更加简洁,可以将next数组整体+1;

于是next数组就出来了
4. 快速得到next数组
1. 手动画图
已知串 S= "babab ", 求 Next 数值序列(模式匹配)
- 首先第一位0,第二位1。这个是固定的。
- 第三位,字符串是“bab”,这时候“bab”的前缀有b,ba;后缀有ab,b,可以看出前后缀相等的最长的字符串只有b,因为b的长度是1,所以这里第三位的next值就是1。
- 第四位,字符串是“baba”,前缀是b,ba,bab;后缀是aba,ba,a。这里可以看出前后缀相等的最长的字符串是ba,长度是2,因此第四位的next值是2。
- 第五位,字符串是“babab”,前缀是b,ba,bab,baba;后缀是abab,bab,ab,b。这里可以看出前后缀相等的最长的字符串是bab,长度是3,因此第五位的next值是3.
- 因此综合起来next值就是0 1 1 2 3
2. 代码实现next数组
void get_next(String T,int next[]){int i=1,j=0;next[1]=0;while(i<T.length){if(j==0||T.ch[i]==T.ch[j]){++i,++j;next[i]=j;}else j=next[j];}
}

5. KMP匹配算法
int Index(SString S,SString T,int next[]){int i=1,j=1;while(i<=S.length&&j<=T.length){//相同的话就一直匹配 if(j==0||S.ch[i]==T.ch[j]){ ++i; ++j; }//不同的话就回溯else{ j=next[j];}}//找到了,(i-1)-(T.length-1)=i-T.lengthif(j>T.length) return i-T.length; //没找到else return 0;
}
相关文章:
字符串模式匹配,经典KMP算法你还不会?我可不允许你不会!
文章目录重点1. 简单模式匹配算法2. 部分匹配值PM的算法(Move j-1 PM[j-1])3. 部分匹配值PM的两次改进(Move j-next[j])4. 快速得到next数组5. KMP匹配算法重点 童鞋们看网上讲解的时候一定要分清楚序列是从0开始还是从1开始&…...
C++操作redis(实现连接池、分布式锁)
文章目录Redis连接池编译项目整体架构使用分布式锁总结Redis连接池 封装hiredis的一些基本操作,redishelper类提供包含连接,放回,存取键,push,pop,执行redis语句和执行lua脚本的函数,连接池是类…...
硬件基础专题-01电阻篇
目录 课程链接 学习目的 电阻 电阻理论讲解 电阻定义 欧姆定律 电阻单位换算 电阻选型考虑 安装方式 常见电阻值 各种贴片电阻的读取方式 确定电阻值的方法 电阻数据手册 电阻测量 电阻的产品应用 零欧姆电阻 热敏电阻 光敏电阻 课程链接 视频专辑 - 硬件…...
【JAVA程序设计】(C00112)基于Springboot+Thymeleaf的在线购物商城——有文档
基于SpringbootThymeleaf的在线购物商城——有文档项目简介项目获取开发环境项目技术运行截图运行视频项目简介 基于Springbootthymeleaf框架的在线购物商城系统,本系统共分为二个角色:管理员和用户 管理员角色包含以下功能: 商品管理、商品…...
shell基础(5)算数计算:运算语法、自增自减
文章目录1. shell算数运算的特点2. 运算符一览3. 运算语法3.1 整形运算3.2. 小数运算 ing4. 自增自减4.1. a与a4.2. 自加1. shell算数运算的特点 Shell 和其它编程语言不同,Shell 不能直接进行算数运算,必须使用数学计算命令。Shell只支持整数运算&#…...
virtio设备input节点
注册virtio_input_node节点,节点类型为VLIB_NODE_TYPE_INPUT。 VLIB_REGISTER_NODE (virtio_input_node) {.name "virtio-input",.sibling_of "device-input",.format_trace format_virtio_input_trace,.flags VLIB_NODE_FLAG_TRACE_SUPP…...
《计算机网络:自顶向下方法》学习笔记——第一章:计算机网络和因特网
计网 第一章 计算机网络和因特网 1.1 什么是因特网 回答这个问题有两种方式 其一,我们能够描述因特网的具体构成,即构成因特网的基本硬件和软件组件;其二,我们能够根据为分布式应用提供服务的联网基础设施来描述因特网。 1.1.…...
PDF 解析格式化输出 API 数据接口
PDF 解析格式化输出 API 数据接口 支持输出 TEXT HTML XML TAG,多种格式输出,超精准识别率。 1. 产品功能 通用的识别接口, 支持标准 PDF 文件解析;多种格式输出,支持 TEXT HTML XML TAG;HTML 包含完美排…...
RL笔记:基于策略迭代求CliffWaking-v0最优解(python实现)
目录 1. 概要 2. 实现 3. 运行结果 1. 概要 CliffWalking-v0是gym库中的一个例子[1],是从Sutton-RLbook-2020的Example6.6改编而来。不过本文不是关于gym中的CliffWalking-v0如何玩的,而是关于基于策略迭代求该问题最优解的实现例。 CliffWalking-v0的…...
350. 两个数组的交集 II
两个数组的交集 II 给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结…...
Android仿微信选择图片
效果展示首先先添加用到的权限<uses-permission android:name"android.permission.INTERNET" /><!--获取手机存储卡权限--><uses-permission android:name"android.permission.READ_EXTERNAL_STORAGE"/><uses-permission android:nam…...
python+嵌入式——串口通信篇(收发解包)
目录前言安装pyserialpyserial大致概括整体流程硬件连接例子(简单版)详细使用serial初始化参数发包收包收包检查包并解包python struct模块结语前言 这几年,自己也做了一些嵌入式机器人。在整个开发的过程中,调通信通常会花费一段比较长的时间ÿ…...
剖析G1 垃圾回收器
简单回顾 在Java当中,程序员在编写代码的时候只需要创建对象,从来不需要考虑将对象进行释放,这是因为Java中对象的垃圾回收全部由JVM替你完成了(所有的岁月静好都不过是有人替你负重前行)。 而JVM的垃圾回收由垃圾回收器来负责,在…...
如何打造一款专属于自己的高逼格电脑桌面
作为一名电脑重度使用者,你是否拥有一款属于你自己的高逼格电脑桌面呢?你是不是也像大多数同学一样,会把所有的内容全部都堆积到电脑桌面,不仅找东西困难,由于桌面内容太多还会导致C盘空间不足,影响电脑的反…...
【C++】string的使用及其模拟实现
文章目录1. STL的介绍1.1 STL的六大组件1.2 STL的版本1.3 STL的缺陷2. string的使用2.1 为什么要学习string类?2.2 常见构造2.3 Iterator迭代器2.4 Capacity2.5 Modifiers2.6 String operations3. string的模拟实现3.1 构造函数3.2 拷贝构造函数3.3 赋值运算符重载和…...
怀念在青鸟的日子
时间过的可真快,一转眼来到了2023年!我初中上完就没有在念,下了学门步入社会,那时的我一片迷茫,不知道该去干什 么,父母说要不去学挖掘机、理发、修车...我思考再三,一个都没有我喜欢的…...
学习记录---Python内置类型
文章目录字符串split()列表常见操作列表相减字典创建普通创建eval(s)添加或更新元素d[t] 1d.update({c: 3}){**d1, **d2} **字典解包装运算符删除元素 d.pop(c)属性d.items()d.keys()d.values()访问元素d[Name]d.get(score)遍历字典for key in dictfor key, values in dict.it…...
Python笔记 -- 列表
文章目录1、列表简介2、修改、添加、删除元素2.1、添加2.2、删除3、排序、倒序4、遍历列表5、创建数值列表6、列表切片7、列表复制8、元组1、列表简介 在Python中用方括号[]表示列表,用逗号隔开表示其元素 通过索引访问列表 names [aa,bb,cc,dd]print(names[0]) …...
谈谈UVM中的uvm_info打印
uvm_info宏的定义如下: define uvm_info(ID,MSG,VERBOSITY) \begin \if (uvm_report_enabled(VERBOSITY,UVM_INFO,ID)) \uvm_report_info (ID, MSG, VERBOSITY, uvm_file, uvm_line); \end 从这里可以看出uvm_info由两部分组成:uvm_report_enabled(VER…...
矩阵理论1 集合上的等价关系(equivalence relations on a set S)
定义 对于一个集合S, 如果集合E⊂SS\mathcal{E} \subset S\times SE⊂SS满足以下条件 自反性: 对于∀s∈S,都有(s,s)∈E\forall s\in S, 都有 (s, s) \in \mathcal{E}∀s∈S,都有(s,s)∈E对称性: (s,t)∈E⇔(t,s)∈E(s,t) \in \mathcal{E} \Leftrightarrow (t,s)\in \mathcal…...
公考教父级教学,不同阶段学员都能适配
备考省考面试,选对讲师真的能少走80%的弯路!最近体验了初心教育钟晓红老师的面试课,彻底被这位“公考面试教父”的实力折服。作为公考面试讲师导师,钟老师的课适配不同阶段学员,整体通过率还在行业里断层领先ÿ…...
OpenClaw性能优化:提升Kimi-VL-A3B-Thinking多模态任务执行效率
OpenClaw性能优化:提升Kimi-VL-A3B-Thinking多模态任务执行效率 1. 为什么需要性能优化? 上周我尝试用OpenClaw对接Kimi-VL-A3B-Thinking多模态模型处理一批产品截图分析任务。原本预计2小时完成的工作,实际运行了整整8小时——期间不仅消耗…...
新手零门槛部署openclaw:快马ai生成手把手配置教程与验证代码
最近在尝试部署openclaw这个开源爬虫框架时,发现网上资料比较零散,对新手不太友好。经过一番摸索,我总结了一套适合零基础同学的部署方案,整个过程在InsCode(快马)平台上测试通过,特别适合想快速上手的朋友。 硬件和系…...
Laravel Stats Tracker迁移升级指南:从旧版本平滑过渡到新版本的完整方案
Laravel Stats Tracker迁移升级指南:从旧版本平滑过渡到新版本的完整方案 【免费下载链接】tracker Laravel Stats Tracker 项目地址: https://gitcode.com/gh_mirrors/tr/tracker Laravel Stats Tracker是一款功能强大的Laravel统计跟踪工具,能够…...
SMUDebugTool终极指南:如何深度调试AMD Ryzen处理器底层硬件
SMUDebugTool终极指南:如何深度调试AMD Ryzen处理器底层硬件 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: http…...
SpringBoot+Vue 学科竞赛管理管理平台源码【适合毕设/课设/学习】Java+MySQL
💡实话实说:有自己的项目库存,不需要找别人拿货再加价,所以能给到超低价格。摘要 随着教育信息化的快速发展,学科竞赛作为培养学生创新能力和实践能力的重要途径,其管理效率的提升成为高校关注的焦点。传统…...
如何精准定制鼠单克隆抗体?
一、为何鼠单克隆抗体仍是定制研发的主流选择?鼠单克隆抗体作为生物医学研究的重要工具,在定制开发领域占据着不可替代的地位。这主要源于其技术体系的成熟性、标准化的操作流程以及广泛的应用验证基础。自杂交瘤技术问世以来,小鼠作为免疫动…...
PIDNet (ArXiv‘2022)语义分割环境配置、PIDNet (ArXiv‘2022)语义分割模型代跑训练、PIDNet (ArXiv‘2022)语义分割模型改进创新PIDNet (Ar
PIDNet (ArXiv2022)语义分割环境配置、 PIDNet (ArXiv2022)语义分割模型代跑训练、 PIDNet (ArXiv2022)语义分割模型改进创新 PIDNet (ArXiv2022)语义分割环境配置:Windows、Ubuntu、Centos、Macos等系统环境,如果电脑拥有显卡,可配置GPU版本…...
Navicat重置工具终极指南:macOS用户免费解锁专业功能的完整方案
Navicat重置工具终极指南:macOS用户免费解锁专业功能的完整方案 【免费下载链接】navicat_reset_mac navicat mac版无限重置试用期脚本 Navicat Mac Version Unlimited Trial Reset Script 项目地址: https://gitcode.com/gh_mirrors/na/navicat_reset_mac 还…...
微信小程序框架详解
小程序包含一个描述整体程序的app实例和多个描述页面的page。其中app由三个文件构成:公共配置app.json、公共样式app.wxss、主体逻辑app.js。每个page最多由四个文件构成:页面配置page.json、页面结构page.wxml、页面样式page.wxss、页面主体逻辑page.js。 微信小程序的主体部…...


