【问题标题】:Simpler KMP prefix table building. What would be wrong with this implementation?更简单的 KMP 前缀表构建。这个实现会有什么问题?
【发布时间】:2018-10-18 23:34:36
【问题描述】:

KMP 算法需要一个前缀表,以便在失败后知道它可以安全地跳过多少个字符。前缀表的总体思路是,它会告诉您对于给定模式P,在给定位置i 和字符C,到C 的后缀与P的前缀:

int[] T = new int[P.length()];
int i = 0;
for (int j = 1; j < P.length(); ++j) {
  if (P.charAt(j) == P.charAt(i)) {
    i++;
  } else {
    i = 0;
  }
  T[j] = i;
}

这就是我想出的。我环顾四周,实现似乎总是不同的。我尝试了几个示例(例如 ABABACA),但我的实现和例如这个KMP prefix table 似乎产生了相同的结果。

谁能告诉我我的实现中的逻辑错误是什么,以及在为 KMP 算法生成正确的前缀表时会失败的输入是什么?

谢谢

【问题讨论】:

    标签: algorithm knuth-morris-pratt


    【解决方案1】:

    您的算法的一个特点是表中的每个条目都比前一个条目多 0 或 1。所以挑战是找到一个字符串,其中表中的条目小于前一个条目,但不为 0。

    这样的字符串之一是“ABACABABC”(来自this wikipedia article)。

    前缀表是

    {0,0,1,0,1,2,3,2,0}  from the linked answer
    {0,0,1,0,1,2,3,0,0}  your proposed code
                   ^------different here
    

    感兴趣的条目是 3 后跟 2。

    考虑当 7 个字符匹配时会发生什么。输入字符串看起来像

    ABACABA?    
    

    在哪里?是不匹配的字符,所以?不是 B。ABA? 可能与 ABAC 匹配,因此前缀长度为 3。

    现在考虑当 8 个字符匹配时会发生什么:

    ABACABAB?
    

    在哪里?不是 C。在这种情况下,AB? 可以匹配 ABA,因此前缀长度为 2。

    这表明前缀表可能有一个小于前一个条目的条目,但不是0。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-22
      • 1970-01-01
      • 2012-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-17
      • 2011-09-28
      相关资源
      最近更新 更多