寻根KMP算法
本人被
已经折磨许久。五战KMP。方知之前理解确实浅。故写此篇。
这是之前那篇,实在是太浅,不过对代码做了注释。https://www.acwing.com/solution/content/131255/
本篇重点说明
暴力及举例可以去看别的博客。本处不赘述。
匹配
观察暴力,相信也知道,每次我们漏掉了些信息。什么信息呢?
假设当前到这就匹配不成功了。
暴力做法:
直接从头开始匹配。
假设移动如这样:
不断向右移动。。。发现了什么?
好像能不能匹配和最上面串没关系吧。由于前半段已经匹配啦,上面等于下面)
更准确的讲,是不是只跟串的前后缀有关系。
因此,我们考虑至少向后移动到什么位置可以继续匹配上面绿圈呢
假设到这。
黄色部分相等。至少移动多少呢?就是使前后缀相等的最大长度。(前后缀不等无法匹配, 又因为至少)
假设我们当前已经求出这个东西。叫做next。
那就容易了。如果蓝圈红圈不匹配,考虑回退,那就回退到next就行了。中间隔下的一定不行,我们知道前后缀不等的,那么一定没法匹配。如果next不行,那就重复这个过程。
代码
求使前后缀相等的最大长度。略变一下。
强调一下:
首先,假设现在j在的位置是
观察
- 使1~i前后缀相等的最大长度 <= 1~ i-1前后缀相等的最大长度+1。这是因为你可以画一下图,如果更大,那就一定不等(1~i-1前后缀已最大),最多扩展i,j+1嘛。
- 其实还是和匹配一样了吧。next[i]肯定要在带上i==j+1的前后缀相等的长度 取最大, 按照暴力思路,你当然会从大到小枚举所有前后缀长度,取第一个行的。实质就是不断右移的过程。
当si!=sj+1时,考虑后退,这个时候又在向右移动了。使前后缀相等,那么回退取值一定只有j,next[j],next[next[j]]....
这是因为你可以任取不在其中的一个数k,那么前后缀就不等了,根本没法匹配。(根据next定义,不在这些不断“最大前后缀相等长度”中,那肯定不等啊)
匹配成功后,j=next[i],重复上述过程。可不就求出来了?
好了那这样就愉快解决了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】