您的位置:首页 > 其它

[Leetcode] Implement strStr()与 KMP算法

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

一个字符串text,记为haystack

一个字符串pattern,记为needle

找出needle在haystack中的匹配

解决方法参见
http://web.stanford.edu/class/cs97si/10-string-algorithms.pdf
有三种:

naive(暴力),检查以每个char开头的配对可能
hash function,对于haystack中每个长度与needle相同的子串求hash function的值,建表。hash function 可以用较大素数的幂指数
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode kmp strStr