【问题标题】:KMP failure function calculationKMP失效函数计算
【发布时间】:2013-04-20 21:49:16
【问题描述】:

我的教授解决了kmp故障函数如下:

index  1 2 3 4 5 6 7 8 9
string a a b a a b a b b
ff     0 1 2 1 2 3 4 5 1

从网上查到的其他文字,我发现可能是错的,我又回去跟他确认,他告诉我他完全正确。有人可以通过简单的逐步方式向我解释为什么他认为这是对还是错?谢谢

【问题讨论】:

  • 您可能需要从失败表中的每个值中减去一个。这取决于您使用的算法。

标签: string-matching knuth knuth-morris-pratt


【解决方案1】:

据我了解该算法,您示例的故障函数应如下所示:

1 2 3 4 5 6 7 8 9
a a b a a b a b b

0 1 0 1 2 3 4 0 0

f - 失败函数(根据定义,这是字符串的最长前缀的长度,也是后缀)

这里是我如何一步一步构建的:

f(a) = 0(一个字母总是 = 0)

f(aa) = 1(一个字母'a'既是前缀又是后缀)

f(aab) = 0(没有相同的后缀和前缀:a != b, aa != ab)

f(aaba) = 1('a'开头和结尾是一样的,但是如果你取2个字母,它们就不相等了:aa != ba)

f(aabaa) = 2(你可以取 'aa' 但不能再取了:aab != baa)

f(aabaab) = 3 (你可以取'aab')

f(aabaaba) = 4(可以取'aaba')

f(aabaabab) = 0 ( 'a' != 'b', 'aa' != 'ab' 等等,不可能是 = 5,所以如 'aabaa' != 'aabab')

f(aabaabbabb) = 0(同样的情况)

【讨论】:

  • 这听起来更像是Z-算法,而不是KMP的失效函数。它们有点相似,但不完全相同。
【解决方案2】:

由于@user1041889 很困惑(也让我很困惑),我将在这里说明 Z 函数和故障函数之间的区别。

失败函数,π[i]

是字符串最长前缀长度的映射和索引,也是后缀

但这可以说是中文,所以我会把它弄糊涂以便真正理解我在说什么:

感兴趣的字符串开头的最长子字符串有多大,等于以索引i结尾的子字符串

或等效:

以索引i 结尾且与感兴趣的字符串开头匹配的最大子字符串的长度是多少

所以在你的例子中:

index  1 2 3 4 5 6 7 8 9
string a a b a a b a b b
ff     0 1 0 1 2 3 4 0 0

我们观察到π[6] = 3,那么以索引 6 结尾且长度为 3 的子字符串是什么? aab!

有趣的是我们以前见过这种情况!

让我们检查一下它确实是最大的一个:baab != aab。是的!

注意这意味着失效函数总是均匀增长。

Z 算法并非如此。

[正在保存草稿以稍后继续]

【讨论】:

    猜你喜欢
    • 2011-09-29
    • 2013-09-11
    • 1970-01-01
    • 2019-10-08
    • 1970-01-01
    • 2013-08-06
    • 1970-01-01
    • 2020-01-29
    • 1970-01-01
    相关资源
    最近更新 更多