[Leetcode] Implement strStr()与 KMP算法

本文详细介绍了KMP算法的原理与实现,包括建立overlap表的两种步骤:预处理和遍历匹配过程。通过实例代码,展示了如何利用KMP算法高效地在字符串中查找模式。同时,提供了通过LeetCode平台验证算法正确性的链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这道题目折腾了我两三天,搞清楚kmp(我原来也上过数据结构的课,为什么对这个完全没有印象)。这个题目可以概述为


一个字符串text,记为haystack

一个字符串pattern,记为needle

找出needle在haystack中的匹配


解决方法参见

http://web.stanford.edu/class/cs97si/10-string-algorithms.pdf

有三种:

  1. naive(暴力),检查以每个char开头的配对可能
  2. hash function,对于haystack中每个长度与needle相同的子串求hash function的值,建表。hash function 可以用较大素数的幂指数
  3. kmp(knuth-Morris-Pratt),以下详细说说
kmp的通用实现有两步:
  • 建立一个overlap的表格,即对于pattern字符串,考虑如果在第j位出现mismatch, 指针j应该回溯多少位
  • 双指针遍历haystack和needle,出现mismatch的时候,指向haystack的指针i不动,j回溯
第一步建立表格的预处理只和needle有关,这是kmp的一大优点,建立的时候有递归的式子可用
表格命名为next,index为j,next的长度和needle相同
如果needle的第一位和haystack的当前位mismatch,显然不用回溯,直接走i的下一位,所以next[0]=0
对于j大于0的情况,如果needle[next[j-1]+1]==needle[j] 有next[j]=next[j-1]+1
否则,next[j]的值需要回查若干位令k满足needle[next[k-1]+1]==needle[j]相等或者k为0位,此时next[j]=k

http://www.matrix67.com/blog/archives/115
给出了伪代码, P为next表格,这里的i相当于上面的j,j相当于上面的k

P[1]:=0;
j:=0;
for i:=2 to m do
begin
   while (j>0) and (B[j+1]<>B[i]) do j:=P[j];
   if B[j+1]=B[i] then j:=j+1;
   P[i]:=j;
end;

第二步使用表格遍历haystack,保持指向haystack的指针前进,调整指向needle的指针。和建立表格时候非常相似的逻辑
如果出现mismatch,根据next表调整needle的指针

j:=0;
for i:=1 to n do
begin
   while (j>0) and (B[j+1]<>A[i]) do j:=P[j];
   if B[j+1]=A[i] then j:=j+1;
   if j=m then
   begin
      writeln('Pattern occurs with shift ',i-m);
      j:=P[j];
   end;
end;

过leetcode的程序可以参考
http://fisherlei.blogspot.com/2012/12/leetcode-implement-strstr.html




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值