AC自动机讲解超详细

本文详细介绍了AC自动机的概念,包括其与Trie和KMP的关系,以及如何构建Fail指针。通过拓扑排序优化AC自动机,降低查询时间复杂度至O(模式串总长)。此外,还讲解了AC自动机在字符串匹配和计数问题中的应用。
摘要由CSDN通过智能技术生成

begin:2019/5/2

update 2020/6/12 更新了LaTeX(咕了好久

感谢大家支持!

AC自动机详细讲解

AC自动机真是个好东西!之前学 K M P KMP KMP N e x t Next Next指针搞晕了,所以咕了许久都不敢开AC自动机,近期学完之后,发现AC自动机并不是很难,特别是对于 K M P KMP KMP​,个人感觉AC自动机 K M P KMP KMP要好理解一些,可能是因为我对树上的东西比较敏感(实际是因为我到现在都不会 K M P KMP KMP)。

很多人都说AC自动机是在 T r i e Trie Trie树上作 K M P KMP KMP,我不否认这一种观点,因为这确实是这样,不过对于刚开始学AC自动机的同学们就一些误导性的理解(至少对我是这样的)。 K M P KMP KMP是建立在一个字符串上的,现在把 K M P KMP KMP搬到了树上,不是很麻烦吗?实际上AC自动机只是有 K M P KMP KMP的一种思想,实际上跟一个字符串的 K M P KMP KMP有着很大的不同。

所以看这篇blog,请放下 K M P KMP KMP,理解好 T r i e Trie Trie,再来学习。

前置技能

1. T r i e Trie Trie(很重要哦)

2. K M P KMP KMP的思想(懂思想就可以了,不需要很熟练)

问题描述

给定 n n n个模式串和 1 1 1个文本串,求有多少个模式串在文本串里出现过

注意:是出现过,就是出现多次只算一次。

默认这里每一个人都已经会了 T r i e Trie Trie

我们将 n n n个模式串建成一颗 T r i e Trie Trie树,建树的方式和建 T r i e Trie Trie完全一样。

假如我们现在有文本串 A B C D B C ABCDBC ABCDBC

我们用文本串在 T r i e Trie Trie上匹配,刚开始会经过 2 、 3 、 4 2、3、4 234号点,发现到 4 4 4,成功地匹配了一个模式串,然后就不能再继续匹配了,这时我们还要重新继续从根开始匹配吗?

不,这样的效率太慢了。这时我们就要借用 K M P KMP KMP的思想,从 T r i e Trie Trie上的某个点继续开始匹配。

明显在这颗 T r i e Trie Trie上,我们可以继续从 7 7 7号点开始匹配,然后匹配到 8 8 8

那么我们怎么确定从那个点开始匹配呢?我们称 i i i匹配失败后继续从 j j j开始匹配, j j j i i i F a i l Fail Fail(失配指针)。

构建Fail指针

F a i l Fail Fail的含义

F a i l Fail Fail指针的实质含义是什么呢?

如果一个点 i i i F a i l Fail Fail指针指向 j j j。那么 r o o t root root j j j的字符串是 r o o t root root i i i的字符串的一个后缀。

举个例子:(例子来自上面的图

i:4     j:7
root到i的字符串是“ABC”
root到j的字符串是“BC”
“BC”是“ABC”的一个后缀
所以i的Fail指针指向j

同时我们发现,“ C C C”也是“ A B C ABC ABC”的一个后缀。

所以 F a i l Fail Fail指针指的 j j j的深度要尽量大。

重申一下 F a i l Fail Fail指针的含义:**((最长的(当前字符串的后缀))**在 T r i e Trie Trie上可以查找到)的末尾编号。

感觉读起来挺绕口的蛤。感性理解一下就好了,没什么卵用的。知道 F a i l Fail Fail有什么用就行了。

F a i l Fail Fail

首先我们可以确定,每一个点 i i i F a i l Fail Fail指针指向的点的深度一定是比 i i i小的。(Fail指的是后缀啊)

第一层的 F a i l Fail Fail一定指的是 r o o t root root。(比深度 1 1 1还浅的只有 r o o t root root了)

设点 i i i的父亲 f a fa fa

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值