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

kmp算法的实现

假设现在有如下场景,有一字符串abcdefg,有另一字符串efg,我们该如何快速从字符串中寻找其子串呢?

不难想到我们有一个显而易见的算法,可以先从主串的第一位开始遍历,将a与e比较,此处明显不匹配,继续讲b与e比较,不匹配,继续一直跳过,直到e和e匹配,我们就将子串和主串各自往下移一位。然后发现f和f是匹配的(假如此处f不匹配会怎么样?例如此时主串为abcdeug,子串不变。那么e和e匹配,但是u和f不匹配,此时就将e和u再次匹配,显然此处也是不匹配的,就继续向下知道一直合适位置。

显然这个算法十分复杂,每次都要进行重复的便利,那么有什么办法可以减少字符串匹配的次数呢?我们有如下场景:

主串:aaaaaaaaaab 子串:aaab,如果按照上面所述的方法,这个匹配显然得每次都进行到子串的最后一位然后匹配失败,再次进行匹配,但是仔细一想,每次都匹配过a了,就是已经做过很多次正确的匹配最后一次匹配失败,那么按理来说我们可以跳过几个已经匹配过的数字然后继续进行匹配?那么该跳过几个字符呢?此时我们就引入了kmp算法中的next数组,这个数组存储了你应该跳过的字符的个数。我们在匹配失败的时候会看最后一个匹配的字符所对应的next数值。

我们先忽略next数组的计算,假设我们已知next数组的大小该怎么进行计算呢?以下是代码实现:
 

next数组对于不同的字符串显然有不同的数组,所以我们该思考怎么进行next数组的计算。

假设有如下场景

abbabbababaaababaaa

abbabaababaa,此处我们在第六位发现不匹配。在第六位之前我们有字符串abbab,对于这个2字符串来说,我们可以找到两个匹配的公共前后缀ab,那么此时kmp算法就教我们叫子串后移到

abbabbababaaababaaa

      abbabaababaa,注意看此处的对齐。将前面三个字符跳过了,此时我们可以在进行一次刚才的操作,再次匹配再次跳过。。。以此类推。(前后缀不能等于子串长度不然没有意义),那么此处next数组的大小为最大公共前后缀长度加1,第一位因为前面没有数字固定为0.

例如abaaab,0,1,1,此时为aba,所以为2,再后abaa,2,abaaa,2,abaaab,3,所以next数组为0112223.

相关文章:

  • 测试专项3:算法测试基础理论速查手册
  • Spring Boot 整合 Apache Flink 教程
  • 二. JAVA数据类型与变量
  • 软考中级-软件设计师 准备
  • OpenWrt开发第4篇:设置开发板的IP-基于Raspberry Pi 4B开发板
  • 2025-03-20 学习记录--C/C++-C 库函数 - toupper()、tolower()、 isspace()
  • Python(冒泡排序、选择排序、插入法排序、快速排序,算法稳定性)
  • 双碳战略下的电能质量革命:解码电力系统的健康密码
  • 服务的拆分数据的迁移
  • Springboot项目搭建(9)-分页与文件上传
  • 中国历史文化名城分布矢量数据
  • 一份1000元机器人开发资金计划表
  • QT编程之PCM音频处理
  • ruoyi 小程序使用笔记
  • 基于CVX优化器的储能电池调峰调频算法matlab仿真
  • P1659 [国家集训队] 拉拉队排练 (manacher 算法)
  • Sampling – Model Context Protocol Specification
  • 缓存监控治理在游戏业务的实践和探索
  • Cursor设置中文教程----两种方法【简单】
  • 统计领域英语专业词汇补充
  • 国际博物馆日|航海博物馆:穿梭于海洋神话与明代造船工艺间
  • 首映|《星际宝贝史迪奇》真人电影,不变的“欧哈纳”
  • 坚决打好产业生态培育攻坚战!陈吉宁调研奉贤区
  • 昔日千亿房企祥生集团约2.03亿元债权被拍卖,起拍价8000万元
  • 临港新片区将新设5亿元启航基金:专门投向在临港发展的种子期、初创型企业
  • 在本轮印巴冲突的舆论场上也胜印度一筹,巴基斯坦靠什么?