java ac自动机_AC自动机原理

最近在看AC自动机的构建和使用,在此做一下记录。因为是边看边写,所以此篇内容可能有错误之处,或者有删改的可能,读者还是以别的教程为准,以免学错了,这篇就当是方便理解吧。

Aho-Corasick自动机是一种多字符串匹配的算法,通过将模式串预处理为确定有限状态自动机,匹配复杂度为O(n),即与模式串的数量和长度无关。疑问:能同时获得匹配字符串的位置吗?如何多次匹配同一字符串?各自的位置呢?

AC算法中有三个核心表,分别是:

success表: 这一步匹配成功了,下一步可以匹配哪些

failure表: 这一步匹配失败了,怎么转移到新的路径匹配

emits表: 匹配到某个节点,可以输出哪些内容

三个核心问题:

1、如何构建这些表?2、如何存储这些表?3、如何查询这些表?

下面分别一一作答。

success表的构建:success非常容易构建,按照需要匹配的字符串构建成一棵树就可以了,如下图中的实线部分,其中0号是root节点,不存储具体字符。这张表里包含了he, hers, his, she这几个单词。

failure表的构建:上图中的失败指针即为虚线,指如果到这一节点匹配成功了,但是在其子节点匹配失败了,该走向哪一个节点。构建方法是这样的:对于一个节点C,标识字符a,顺着C的父亲节点的失配指针走,走到第一个有儿子也是a的节点T,那么C的失败指针就指向T的标识a的儿子节点。如果找不到这个节点,那么失败指针指向Root。在实际操作时,这个建构过程要求父亲节点的失败指针已经建好,而且一层层都要建好,所以采用bfs实现failure表的构建。比如,在上图中,节点5的父节点为4,4的失败指针指向1,1的子节点中包含字符e的为2,所以5的失败指针指向2。

emits表的构建:猜测把失败指针指向的节点的内容copy过来,比如上图中,节点5的失败指针指向2,2是一个emit节点,包含的内容是he,把he拷贝到节点5的emit表中即可。用链表会更好吧

success表的存储:大部分实现都是采用了字典,不过性能可能会受影响,码农场采用了DoubleArrayTrie实现存储,说是会快很多,我研究一下

参考博客:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值