码迷,mamicode.com
首页 > 其他好文 > 详细

从Trie谈到AC自动机

时间:2015-04-12 00:00:24      阅读:375      评论:0      收藏:0      [点我收藏+]

标签:

ZJOI的SAM让我深受打击,WJZ大神怒D陈老师之T3是SAM裸题orz...我还怎么混?暂且写篇`从Trie谈到AC自动机`骗骗经验.

Trie

Trie是一种好玩的数据结构.它的每个结点存的是字母,因此得名`字母树`.

出一张图让大家感受下.

技术分享

(image powered by SaiBu NaoCu)

上面那是一棵插入了

ape,app,applicant,application,bake,ban,banana

等词的Trie.红色结点表示接受态.

显然,查找时只需顺着链照下来,插入只需边查找边插入.

(删除只需除去接受态,或此时在它没有子结点时删除到它的最近接受态父结点)

好懂好写高效率.

AC自动机

AC自动机是一种基于Trie的数据结构.它是一个真正的自动机.

AC自动机,简单地说就是加了一些奇怪东西的Trie.

技术分享

(powered by cocoa....Cacoo)

实线表示Trie上的路径,虚线表示Fail指针.

Fail指针是什么呢?当你在这个结点上时,对于下一个字符失匹配时你要走的路.很类似于KMP的next数组.

它的定义也是基本一样的.最长有相同前缀的后缀(的那个前缀的最后一个字母结点的指针).

使用起来更是一样.计算也是一样的.顺着fat(s[p-1])的fail(next[k])跳到可以匹配为止.

简单吧?和KMP很像.

那么问题又来了.怎么输出呢?

我们再画个图想想.

技术分享

原来,顺着Fail指针一直走下去即可啊...

那么我们就有了用AC自动机匹配的算法.

技术分享

匹配第一个`A`,从root往下找

技术分享

找到匹配,A的匹配加一.向下寻找下一个字符找到Null.

技术分享

 

因Fail指针回跳到root.寻找字符C.

技术分享

寻找字符B.不是接受态,继续.

技术分享

A是一个接受态.沿着Fail指针走回去输出结果.

技术分享

-------------------

技术分享

匹配C失跳.

技术分享

------------------------------

技术分享

...........................

技术分享

...................最终

技术分享

结果

技术分享

构造一个AC自动机

那么,如何构造一个AC自动机呢?

显然可以在每加入一个结点时沿着它的父亲的Fail指针走,走到第一个有相同字符子结点的找到那个子结点,将Fail指向那个结点;如果到root还没找到有同字符子结点,将Fail指向root.

这是在线的做法.离线当然可以用BFS解决,这样保证了当一个结点被处理时它的父亲那层的结点已经处理完.Fail结点最近也只可能在父亲那层.复杂度应与在线办法相同.

Update: 犯了个SB错,AC自动机不可在线.原因Fail指针可能改变.

图表地址:https://cacoo.com/diagrams/xqj6UFk5zcllgHGW

从Trie谈到AC自动机

标签:

原文地址:http://www.cnblogs.com/tmzbot/p/4418709.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!