首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >KMP前缀表直观

KMP前缀表直观
EN

Stack Overflow用户
提问于 2012-12-13 01:37:18
回答 2查看 2.1K关注 0票数 4

如我所见,在KMP中构建故障/前缀表的主要函数(在所有在线资源中,甚至在此answer中)如下所示:

代码语言:javascript
复制
int j = 0;  
    for (int i = 1; i < pattern.length(); i++) {  
      while (j > 0 && pattern.charAt(j) != pattern.charAt(i)) {   
        j = failure[j - 1];  
      }  
      if (pattern.charAt(j) == pattern.charAt(i)) {   
        j++;   
      }  
      failure[i] = j;  
    }

我不能理解这一部分:

j = failure[j - 1];

为什么我们不做j--来返回字符串呢?我们如何知道使用失败的表更新j是正确的?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-12-13 02:19:09

如果故障表的第i个条目是长度为i的模式的前缀的最长后缀-前缀匹配的长度,则KMP字符串匹配是正确的。

注意,如果A[0..k]A[0..i]的后缀-前缀匹配,那么A[0..k]要么是A[0..i]的最长后缀-前缀匹配,要么是所述最长后缀-前缀匹配的后缀-前缀匹配。

当你把这两件事放在一起时,结果是我们希望failure[i]pattern[0..i]的最长后缀-前缀匹配的长度。KMP预处理使用以下事实归纳构建failure

如果A[0..i]的最长后缀-前缀匹配不为空,则去掉最后一个字符将得到A[0..i-1]的一些后缀-前缀匹配。

因此,A[0..i]的最长后缀-前缀匹配要么是空的,要么是通过将A[0..i-1]的最长后缀-前缀匹配扩展一个字符或将该最长后缀-前缀匹配的后缀-前缀匹配扩展一个字符而形成的。前面字符的失败函数为您提供了一种简单的方法来迭代pattern[0..i-1]的所有后缀-前缀匹配。

票数 3
EN

Stack Overflow用户

发布于 2021-02-07 03:41:23

这个视频确实有助于我们清楚地理解为什么我们需要做j= failurej - 1;而不是j--;

https://www.youtube.com/watch?v=tWDUjkMv6Lc&feature=emb_logo

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13845435

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档