AC自动机 P1366

  来说一下AC自动机.

  大概就是给定一堆单词和一个很长的字符串,求字符串内这些单词出现的次数.如果只有两个字符串进行匹配可以写KMP,如果很多呢?我会字典树+KMP.

  来复习KMP的核心思想:在A串中求B是否出现过,我们利用已经匹配好的B的后缀,当失配时尽可能的让指针在B上少向前跳.为此我们做出一个next数组表示失配时B上的指针应该跳到的位置.把这个思想放在字典树上,每个字典树上的节点都记录"当在这里失配时指针应该跳到的位置".

  现在是否理解了呢?

  来看例题吧.

  当时是用暴力枚举O(m*maxlen)在字典树上跑了跑,甚至比AC自动机快2333(原文:https://www.cnblogs.com/qywyt/p/10256095.html).

  现在考虑如何O(m+maxlen)的A掉?来看样例的几个单词.

  假设你现在会写代码,对着这个图看一会,我们可以对这个字典树每个点都安上一个指针指向应该跳的位置.

扫描二维码关注公众号,回复: 5157203 查看本文章

  应该怎么做呢?对于一个节点,它的失败指针要找自己父亲的失配指针所指的节点,如果有对应儿子就是它,否则继续向上跳失配指针,继续判断是否有对应儿子.

  比如找sh的指针,它要看s的失配指针,发现指向了根节点,并且根节点有对应的儿子:h,于是sh的指针是h.

  比如找she的指针,它要看sh的失配指针,发现指向了h,而且h有对应的儿子e,于是she的指针是he.

  这里对应的儿子指的是自己最后的那一个字母.

  

  

猜你喜欢

转载自www.cnblogs.com/qywyt/p/10358932.html