【问题标题】:Prefix-function computation in Knuth-Morris-Pratt AlgorithmKnuth-Morris-Pratt 算法中的前缀函数计算
【发布时间】:2015-08-05 06:17:34
【问题描述】:

所以对于下面的子字符串

1 2 3 4 5 6 7 8 9 10 11

a b c d a b c d a b  x

前缀函数是什么?我和我的一个朋友计算了它,我们得到了不同的结果,我的是:

a b c d a b c d a b x

0 0 0 0 1 2 3 4 5 6 2

和他的:

a b c d a b c d a b x

0 0 0 0 1 2 3 4 1 2 0

如果我错了,那是为什么?

【问题讨论】:

  • 您能否添加一个简短的大纲来说明您要查找的内容。并不是我们所有人都有这本书……
  • 伪码是 m ← length[p] a[1] ← 0 k ← 0 for q ← 2 to m do while k > 0 and p[k + 1] , p[q ] do k ← a[k] end while if p[k + 1] = p[q] then k ← k + 1 end if a[q] ← k end for return u
  • @user3848412 请将您的伪代码放入您的问题中,它有助于其他人阅读和关注您的问题:)

标签: algorithm substring knuth-morris-pratt


【解决方案1】:

前缀表应该是:

a b c d a b c d a b x
0 0 0 0 1 2 3 4 5 6 0

所以给出的两个版本都不正确。

表格的最后一个条目

a b c d a b c d a b x
0 0 0 0 1 2 3 4 5 6 2
                    ^
                    |
                this one

正确地说,a b c d a b c d a b x 的长度为 2 的后缀 b x 也必须是长度为 2 的前缀,即 a b

如果前缀表中的条目不为零,则相应的前缀和后缀已在下表中标记:

a                       0
a b                     0
a b c                   0
a b c d                 0

a  b c d a              1
-
         =
a b c d a b             2
---
        ===

a b c d a b c           3
-----
        =====

a b c d a b c d         4
-------
        =======

a b c d a b c d a       5
---------
        =========

a b c d a b c d a b     6
-----------
        ===========

a b c d a b c d a b  x   0

【讨论】:

  • 感谢您的详细解释!
【解决方案2】:

我在 java 中的 KMP 函数:

public int[] KMP(String val) {
    int i = 0;
    int j = -1;
    int[] result = new int[val.length() + 1];
    result[0] = -1;
    while (i < val.length()) {
        while (j >= 0 && val.charAt(j) != val.charAt(i)) {
            j = result[j];
        }
        j++;
        i++;
        result[i] = j;
    }
    return result;

}

前缀数组的结果:

[-1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 0]

【讨论】:

    【解决方案3】:

    您的答案都不正确。前缀函数或部分匹配表如下:

    a b c d a b c d a b x
    
    0 0 0 0 1 2 3 4 5 6 0
    

    你的答案在索引 10 之前是正确的。但是在最后一个索引中你做错了。部分匹配表的索引 11 的值为 0 的原因是因为没有正确的前缀可以匹配到索引 11 的字符串的任何正确的后缀。因为该位置的所有正确后缀都将以 x 结尾,并且该位置没有正确的前缀将以 x 结尾。

    如果您在理解前缀函数或部分索引表的实际含义时遇到问题,可以查看此document。它有一个很好的解释。希望对您有所帮助。

    【讨论】:

    • 感谢您的回答和链接,非常感谢!
    • @user3848412 如果它对您有帮助,也许赞成票不会对您造成任何伤害,不是吗? :P
    【解决方案4】:

    你的两个答案都是错误的。正确的将是

    a b c d a b c d a b x
    
    0 0 0 0 1 2 3 4 5 6 0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-21
      • 2020-12-07
      • 2014-05-01
      • 2014-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-13
      相关资源
      最近更新 更多