当前位置: 首页 > news >正文

字符串模式匹配,经典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的算法&#xff08;Move j-1 PM[j-1]&#xff09;3. 部分匹配值PM的两次改进&#xff08;Move j-next[j]&#xff09;4. 快速得到next数组5. KMP匹配算法重点 童鞋们看网上讲解的时候一定要分清楚序列是从0开始还是从1开始&…...

C++操作redis(实现连接池、分布式锁)

文章目录Redis连接池编译项目整体架构使用分布式锁总结Redis连接池 封装hiredis的一些基本操作&#xff0c;redishelper类提供包含连接&#xff0c;放回&#xff0c;存取键&#xff0c;push&#xff0c;pop&#xff0c;执行redis语句和执行lua脚本的函数&#xff0c;连接池是类…...

硬件基础专题-01电阻篇

目录 课程链接 学习目的 电阻 电阻理论讲解 电阻定义​ 欧姆定律​ 电阻单位换算 电阻选型考虑 安装方式 常见电阻值 各种贴片电阻的读取方式 确定电阻值的方法 电阻数据手册 电阻测量 电阻的产品应用​ 零欧姆电阻 热敏电阻 光敏电阻 课程链接 视频专辑 - 硬件…...

【JAVA程序设计】(C00112)基于Springboot+Thymeleaf的在线购物商城——有文档

基于SpringbootThymeleaf的在线购物商城——有文档项目简介项目获取开发环境项目技术运行截图运行视频项目简介 基于Springbootthymeleaf框架的在线购物商城系统&#xff0c;本系统共分为二个角色&#xff1a;管理员和用户 管理员角色包含以下功能&#xff1a; 商品管理、商品…...

shell基础(5)算数计算:运算语法、自增自减

文章目录1. shell算数运算的特点2. 运算符一览3. 运算语法3.1 整形运算3.2. 小数运算 ing4. 自增自减4.1. a与a4.2. 自加1. shell算数运算的特点 Shell 和其它编程语言不同&#xff0c;Shell 不能直接进行算数运算&#xff0c;必须使用数学计算命令。Shell只支持整数运算&#…...

virtio设备input节点

注册virtio_input_node节点&#xff0c;节点类型为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 什么是因特网 回答这个问题有两种方式 其一&#xff0c;我们能够描述因特网的具体构成&#xff0c;即构成因特网的基本硬件和软件组件&#xff1b;其二&#xff0c;我们能够根据为分布式应用提供服务的联网基础设施来描述因特网。 1.1.…...

PDF 解析格式化输出 API 数据接口

PDF 解析格式化输出 API 数据接口 支持输出 TEXT HTML XML TAG&#xff0c;多种格式输出&#xff0c;超精准识别率。 1. 产品功能 通用的识别接口&#xff0c; 支持标准 PDF 文件解析&#xff1b;多种格式输出&#xff0c;支持 TEXT HTML XML TAG&#xff1b;HTML 包含完美排…...

RL笔记:基于策略迭代求CliffWaking-v0最优解(python实现)

目录 1. 概要 2. 实现 3. 运行结果 1. 概要 CliffWalking-v0是gym库中的一个例子[1]&#xff0c;是从Sutton-RLbook-2020的Example6.6改编而来。不过本文不是关于gym中的CliffWalking-v0如何玩的&#xff0c;而是关于基于策略迭代求该问题最优解的实现例。 CliffWalking-v0的…...

350. 两个数组的交集 II

两个数组的交集 II 给你两个整数数组 nums1 和 nums2 &#xff0c;请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数&#xff0c;应与元素在两个数组中都出现的次数一致&#xff08;如果出现次数不一致&#xff0c;则考虑取较小值&#xff09;。可以不考虑输出结…...

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模块结语前言 这几年&#xff0c;自己也做了一些嵌入式机器人。在整个开发的过程中&#xff0c;调通信通常会花费一段比较长的时间&#xff…...

剖析G1 垃圾回收器

简单回顾 在Java当中&#xff0c;程序员在编写代码的时候只需要创建对象&#xff0c;从来不需要考虑将对象进行释放&#xff0c;这是因为Java中对象的垃圾回收全部由JVM替你完成了(所有的岁月静好都不过是有人替你负重前行)。 而JVM的垃圾回收由垃圾回收器来负责&#xff0c;在…...

如何打造一款专属于自己的高逼格电脑桌面

作为一名电脑重度使用者&#xff0c;你是否拥有一款属于你自己的高逼格电脑桌面呢&#xff1f;你是不是也像大多数同学一样&#xff0c;会把所有的内容全部都堆积到电脑桌面&#xff0c;不仅找东西困难&#xff0c;由于桌面内容太多还会导致C盘空间不足&#xff0c;影响电脑的反…...

【C++】string的使用及其模拟实现

文章目录1. STL的介绍1.1 STL的六大组件1.2 STL的版本1.3 STL的缺陷2. string的使用2.1 为什么要学习string类&#xff1f;2.2 常见构造2.3 Iterator迭代器2.4 Capacity2.5 Modifiers2.6 String operations3. string的模拟实现3.1 构造函数3.2 拷贝构造函数3.3 赋值运算符重载和…...

怀念在青鸟的日子

时间过的可真快&#xff0c;一转眼来到了2023年&#xff01;我初中上完就没有在念&#xff0c;下了学门步入社会&#xff0c;那时的我一片迷茫&#xff0c;不知道该去干什 么&#xff0c;父母说要不去学挖掘机、理发、修车...我思考再三&#xff0c;一个都没有我喜欢的&#xf…...

学习记录---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中用方括号[]表示列表&#xff0c;用逗号隔开表示其元素 通过索引访问列表 names [aa,bb,cc,dd]print(names[0]) …...

谈谈UVM中的uvm_info打印

uvm_info宏的定义如下&#xff1a; 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由两部分组成&#xff1a;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…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...

JVM虚拟机:内存结构、垃圾回收、性能优化

1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案

目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后&#xff0c;迭代器会失效&#xff0c;因为顺序迭代器在内存中是连续存储的&#xff0c;元素删除后&#xff0c;后续元素会前移。 但一些场景中&#xff0c;我们又需要在执行删除操作…...

Kafka主题运维全指南:从基础配置到故障处理

#作者&#xff1a;张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1&#xff1a;主题删除失败。常见错误2&#xff1a;__consumer_offsets占用太多的磁盘。 主题日常管理 …...

ubuntu22.04有线网络无法连接,图标也没了

今天突然无法有线网络无法连接任何设备&#xff0c;并且图标都没了 错误案例 往上一顿搜索&#xff0c;试了很多博客都不行&#xff0c;比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动&#xff0c;重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...