串 - KMP算法
数据结构算法中重中之重。肯定考。Needless to say, 除了蛮力算法之外, 据说还有 30+ 种知名算法。
网上搜了点资料,比较冗长。
1.自己使用过的资料
王道计算机考研 数据结构 -- 原因:讲课比较容易听得进去
https://www.bilibili.com/video/BV1b7411N798?p=40&spm_id_from=pageDriver&vd_source=63764dd9776224d187bddddb05bf9f3f
学堂在线 邓俊辉 数据结构(下) -- 比王道更甚
https://www.xuetangx.com/learn/THU08091002048/THU08091002048/14768880/video/30260006
2.未使用的资料
KMP算法详解 字节跳动工程师写的,这次先不看了
https://zhuanlan.zhihu.com/p/83334559
KMP算法详解-彻底清楚了(转载+部分原创)
https://www.cnblogs.com/dusf/p/kmp.html
很详尽KMP算法(厉害)
https://www.cnblogs.com/zzuuoo666/p/9028287.html
王道考研 主算法
学堂在线 主算法
buildNext()
buildNext() 改进版本
针对该算法,ShoelessCai 打算用几个问题来梳理清楚:
1. 算法返回什么? 返回的是 主串的位置。从代码上看是 i - j 其实就是主串绝对位置。
2. 算法输入什么? 主串、模式串(较短的)、Next数组(记录模式串位置,记住,Next[] 长度与模式串一致,并且可由 模式串直接计算得出)
3. 基本思想:
(1)如果匹配失败的时候,失败的位置记录为 j,那么,我从 j+1 再开始和模式串匹配。
(2)如果模式串(较短的)内部也有较多重复,例如 ababaaa。在某些位置,还可以往后面多跳一格
4. Next[] 长度和模式串(较短的)一致。
(A) 构造方法-I(王道):
匹配 SLOT 之前最长子串,比较前缀、后缀重叠的 SLOTS 个数,姑且称为 N。Next[] 中的元素为 N+1
(B) 构造方法-II(学堂):
如果 匹配成功,则两个指针 i, j 均后移
如果 匹配不成功,但是 t<0 (从第一个字符开始匹配的情况),则 Next[j] = t 。直接将 t 返回给 Next[]
算法效果:失配后回到上一个一样的字符的前一个位置,再失败,回到上上个一样字符的前一个位置。见下文 next_generate_1()
关于 NEXT[]
发现用语言表述还是显得信息量太过少了。那就贴代码。
Python 版本 -- 考试的时候也是看思路,这一点我倒不怀疑。
'''-------------------------- 408/912 关于串 KMP算法 ----------------------------''' import numpy as np import pandas as pd
函数准备:1. Next构造 2. Next 构造改进 3.主函数
# --- 两个函数, next_generate() && kmp_compare() def next_generate(str_in): m=len(str_in); j=0; cnt=0 N=[]; N.append(-1); t=-1; # -- t 为指针 while(j<m-1 and cnt < 1000): if( t<0 or (str_in[j] == str_in[t]) ): j=j+1; t=t+1 N.append(t) else: t=N[t] cnt=cnt+1 return N # --- 改进:失配后,回到上个匹配过的位置,上个匹配的也失败,则回到上上个 # --- 注意是i-1 position def next_generate_1(str_in): m=len(str_in); j=0; cnt=0 N=[]; N.append(-1); t=-1; # -- t 为指针 while(j<m-1 and cnt < 1000): if( t<0 or (str_in[j] == str_in[t]) ): j=j+1; t=t+1 if ( str_in[j] != str_in[t] ): tmp_out=t else: tmp_out=N[t] N.append(tmp_out) else: t=N[t] cnt=cnt+1 return N # --- 主程序 def kmp_compare(str_short, str_long, next_mode=1): # -- generate NEXT[] if ( next_mode==1 ): next_ind = next_generate(str_short) elif ( next_mode==2 ) : next_ind = next_generate_1(str_short) else: print("Next Generation Wrong! \n") return -1 print("Next: ", next_ind) # -- 双指针 n=len(str_long); i=0; m=len(str_short); j=0; cnt=0 while( j<m and i<n ): if( j<0 or str_long[i]==str_short[j] ): i=i+1 j=j+1 else: j = next_ind[j] cnt=cnt+1 del next_ind print("Calculation Round: ", cnt, "\n") return i-j
调用函数的部分
str_l="duovwababaaaacdfbivf" str_s="ababaaaa" # --- 调整 next_mode =1/2 设置不同的 Next[] 构造 tmp = kmp_compare(str_s, str_l, next_mode=2) print("The long string: ", str_l, "\n And the short string: ", str_s, "\n") print("The outcome position: ", tmp)
执行结果
欢迎关注 ShoelessCai.com 。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)