首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Haskell中的Knuth-Morris-Pratt算法

Haskell中的Knuth-Morris-Pratt算法
EN

Stack Overflow用户
提问于 2013-05-22 22:21:56
回答 1查看 1.1K关注 0票数 11

我很难理解Knuth-Morris-Pratt算法在Haskell中的实现。

http://twanvl.nl/blog/haskell/Knuth-Morris-Pratt-in-Haskell

特别是,我不理解自动机的结构。我知道它使用“打结”的方法来构造它,但我不清楚,我也不知道为什么它应该具有正确的复杂性。

我想知道的另一件事是,您是否认为这种实现可以很容易地推广到实现Aho-Corasick算法。

感谢您的回答!

EN

回答 1

Stack Overflow用户

发布于 2013-05-23 03:25:32

下面是算法:

代码语言:javascript
复制
makeTable :: Eq a => [a] -> KMP a
makeTable xs = table
   where table = makeTable' xs (const table)

makeTable' []     failure = KMP True failure
makeTable' (x:xs) failure = KMP False test
   where  test  c = if c == x then success else failure c
          success = makeTable' xs (next (failure x))

使用它,让我们看一下为“shoeshop”构造的表:

代码语言:javascript
复制
makeTable "shoeshop" = table0

table0 = makeTable' "shoeshop" (const table0)
       = KMP False test0

test0 c = if c == 's' then success1 else const table0 c
        = if c == 's' then success1 else table0

success1 = makeTable' "hoeshop" (next (const table0 's'))
         = makeTable' "hoeshop" (next table0)
         = makeTable' "hoeshop" test0
         = KMP False test1

test1 c = if c == 'h' then success2 else test0 c

success2 = makeTable' "oeshop" (next (test0 'h'))
         = makeTable' "oeshop" (next table0)
         = makeTable' "oeshop" test0
         = makeTable' "oeshop" test0
         = KMP False test2

test2 c = if c == 'o' then success3 else test0 c

success3 = makeTable' "eshop" (next (test0 'o'))
         = makeTable' "eshop" (next table0)
         = makeTable' "eshop" test0
         = KMP False test3

test3 c = if c == 'e' then success4 else test0 c

success4 = makeTable' "shop" (next (test0 'e'))
         = makeTable' "shop" (next table0)
         = makeTable' "shop" test0
         = KMP False test4

test4 c = if c == 's' then success5 else test0 c

success5 = makeTable' "hop" (next (test0 's'))
         = makeTable' "hop" (next success1)
         = makeTable' "hop" test1
         = KMP False test5

test5 c = if c == 'h' then success6 else test1 c

success6 = makeTable' "op" (next (test1 'h'))
         = makeTable' "op" (next success2)
         = makeTable' "op" test2
         = KMP False test6

test6 c = if c == 'o' then success7 else test2 c

success7 = makeTable' "p" (next (test2 'o'))
         = makeTable' "p" (next success3)
         = makeTable' "p" test3
         = KMP False test7

test7 c = if c == 'p' then success8 else test3 c

success8 = makeTable' "" (next (test3 'p'))
         = makeTable' "" (next (test0 'p'))
         = makeTable' "" (next table0)
         = makeTable' "" test0
         = KMP True test0

注意success5是如何使用消耗的's‘来回溯模式的初始's’的。

现在来看看在执行isSubstringOf2 "shoeshop" $ cycle "shoe"时会发生什么。

可以看到,当test7无法匹配'p‘时,它会退回到test3来尝试匹配'e',这样我们就可以在success4success5success6success7中无限循环。

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

https://stackoverflow.com/questions/16694306

复制
相关文章

相似问题

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