AC自动机萌新讲解

刚刚拿到一道就是简单的多模式串匹配,心想“噫.AC自动机么……我怎么不会啊”
所以自己瞎扯一点+书(《ACM-ICPC程序设计系列-算法设计与实现》)上摘点来,加深一下印象。


概述:

著名的多模式串匹配算法之一。

构造与原理:

其实很纠结,到底是先讲原理还是先讲构造。因为原理。。。基于构造。。好难讲。
(1)构造一棵Trie,作为AC自动机的搜索数据结构。
(2)构造fail指针,使当前字符失配的时候跳转到具有最长公共前后缀的字符继续匹配。

比如KMP算法中当主串与模式串某一位置不匹配的时候,
啪!移动找出最长的相同的前缀和后缀并使他们重叠,对于模式串来说,我们会提前计算出每个匹配失败的位置应该移动的距离。

同样fail指针就是在干这样的事,可以利用fail指针进行跳转。BFS构造fail指针。
(3)
该干嘛干嘛。

举例

(为了充分 理解 感受 到fail指针对于匹配的作用)
问题:
现有5个单词:say,she,shr,he,her.给定字符串yasherhs. 问多少个单词在字符串中出现过。

首先先建好Trie树(不讲了= =
这里写图片描述
root 是 Trie 的入口,没有实际含义
然后构造 fail指针 吧!(BFS)
(1)root入队,第一次循环时处理与root相连的字符,也就是各个单词的第一个字符h和s.[因为第一个字符不匹配的时候不需要重新匹配,所以第一个字符都指向root]对应图中(1),(2)两条虚线。h,s节点入队。
(2)第二次循环时,h 出队,[p指针]指向h节点的 fail指针指向的节点–>p=root=NULL,说明匹配序列为空,则把 e节点的fail指针指向root,表示没有匹配序列,对应图中(3)虚线,e节点入队。
(3)s出队,第一个a节点类似第(2)步e节点,a节点的fail指针指向root(图中(4)虚线),a入队;对于第二个节点h,p指针指向s的fail指针,p->next[i] != NULL(root 有h这个字节点),这样便把左边那个h节点的fail指针指向右边那个root的儿子节点,对应图中(5);
…….
(X)再讲一个有意义的fail指针,对于左边那个e,当左边h节点出队,[p指针]指向h_fail指针=右边的h节点,右h->next[e] != NULL ,所以左e节点的fail指针指向右e节点,对应图中(8)。
构造………………………结束
这里写图片描述
然后对应问题,扫描吧!
对于模式串:yasherhs.
(1)对于当 i = 0,1 时,Trie 中没有对应的路径,故不作任何操作。
(2)当 i = 2,3,4 时,指针 p(指向当前匹配的字符) 走到左下节点e,因为节点e的count信息为1(指存在这个点为某个单词的结尾),所以答案ans++,然后标记掉count值为-1,避免重复计算。最后temp指向e节点的fail指针所指向的节点继续查找,知道最后temp指向root,退出循环。显然在刚刚 左e节点的fail指针指向右e节点,答案再次+1.—->表示找到了两个单词she,he.
(3)当 i = 5 时,此时p指向右节点e,然后指向r节点,答案ans++.
(4)最后 i = 6,7 时,无果,卒。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值