秉着能偷懒就偷懒的精神,关于AC自动机本来不想看的,但是HanLp的源码中用户自定义词典的识别是用的AC自动机实现的。唉~没办法,还是看看吧

AC自动机理论

Aho Corasick自动机,简称AC自动机,要学会AC自动机,我们必须知道什么是Trie,也就是字典树。Trie树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。之前已经写过关于Tire与双数组Tire(Double Array Tire,以下简称DAT)的文章

AC自动机的优点

AC的优点其实包括了所有Tire树的优点,而且更加强大,考虑下面的问题

对一个长字符串S,给定一个模式串T,查看模式串T是否在S中出现过?

这个问题简单的算法就是便利S与T中的字符逐个比较,不一致则移到S的下一个字符。这种算法最坏情况下的时间复杂度是O(len(S) * len(T))

而广为人知的KMP算法就是省去了逐个比较的过程,而是直接按照next数组中的内容来进行查找,复杂度为O(len(S) + len(T))

而AC自动机较之于DAT的优点就是增加一个fail表,而省去在DAT多模式匹配时无所谓的回溯,(不过后来HanLp的作者做了实验,效率不如DAT呢。)

AC自动机的构造

知道了AC的强大,下面来看AC的构造,构造之前,先看一张AC的图,对字典{FG,HE,HERS,HIS,SHE}构造的Tire树就如下图所示:

乍一看这个图很复杂,其实,只是在TIRE的基础上,对每个节点,加上了一个fail指针,如图中的虚线所示

AC自动机的构造

AC建立是构建在TIRE基础上的,DAT的两要素为BASE与CHECK表,而AC的三要素为goto表,fail表与output表

goto: 即分支与儿子节点

fail :某状态匹配失败,回到fail所指状态继续匹配

output表: 状态对应的输出

把大象装冰箱分3步,所以AC构造过程也分3步:

1. 对字典建立TIRE树结构,建立过程中  goto表也随之建好(即指向子节点的指针),output表初步建成,之后还要根据fail指针去扩充output,下图"[]"中的内容即为初步的output表,对应于字典中的下标

2. 步骤1生成的TIRE树,虽然有树形结构,但状态值都为0,下面用TIRE构造DAT,并且对状态State赋值。

  注意,构造过程中,对是一个词的节点,即图中的绿色节点,在构造DAT时,会长生一个子节点,即标识一个词的结尾,类似与上一篇中提到的叶节点结构,到增加的子节点的转移字符取0即可,新增节点的state值即为父节点的base值

3. 遍历带有状态的TIRE,构造fail表与output表。

构造失败指针的原理: 对某个节点,其产生于字母C,沿着此节点的父节点的失败指针走,知道某个节点,他的分支状态中也有字母C,然后把当前节点的失败指针指向那个分支C指向的儿子节点,如果一直啊到root都没有这样的节点,则失败指针指向root即可。原理同KMP算法,不明白可以谷歌之。构造完后的图即如第一张图所示。

下图即构造完成后,各个表中的内容:

至此  AC自动机便构造完成了,接下来就看看怎么用它去分词了。

参考资料

Aho Corasick自动机结合DoubleArrayTrie极速多模式匹配

中文分词系列(二) 基于双数组Tire树的AC自动机的更多相关文章

  1. 中文分词系列(一) 双数组Tire树(DART)详解

    1 双数组Tire树简介 双数组Tire树是Tire树的升级版,Tire取自英文Retrieval中的一部分,即检索树,又称作字典树或者键树.下面简单介绍一下Tire树. 1.1 Tire树 Trie ...

  2. 从Trie树到双数组Trie树

    Trie树 原理 又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种.它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,能在常数时间O(len)内实现插入和查 ...

  3. 双数组Trie树(DoubleArrayTrie)Java实现

    http://www.hankcs.com/program/java/%E5%8F%8C%E6%95%B0%E7%BB%84trie%E6%A0%91doublearraytriejava%E5%AE ...

  4. Ansj分词双数组Trie树实现与arrays.dic词典格式

    http://www.hankcs.com/nlp/ansj-word-pairs-array-tire-tree-achieved-with-arrays-dic-dictionary-format ...

  5. 中文分词实践(基于R语言)

    背景:分析用户在世界杯期间讨论最多的话题. 思路:把用户关于世界杯的帖子拉下来.然后做中文分词+词频统计,最后将统计结果简单做个标签云.效果例如以下: 兴许:中文分词是中文信息处理的基础.分词之后.事 ...

  6. Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401开发

    Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...

  7. [转]双数组TRIE树原理

    原文名称: An Efficient Digital Search Algorithm by Using a Double-Array Structure 作者: JUN-ICHI AOE 译文: 使 ...

  8. 双数组Trie树 (Double-array Trie) 及其应用

    双数组Trie树(Double-array Trie, DAT)是由三个日本人提出的一种Trie树的高效实现 [1],兼顾了查询效率与空间存储.Ansj便是用DAT(虽然作者宣称是三数组Trie树,但 ...

  9. 双数组trie树的基本构造及简单优化

    一 基本构造 Trie树是搜索树的一种,来自英文单词"Retrieval"的简写,可以建立有效的数据检索组织结构,是中文匹配分词算法中词典的一种常见实现.它本质上是一个确定的有限状 ...

随机推荐

  1. 模拟+思维 HDOJ 5319 Painter

    题目传送门 /* 题意:刷墙,斜45度刷红色或蓝色,相交的成绿色,每次刷的是连续的一段,知道最终结果,问最少刷几次 模拟+思维:模拟能做,网上有更巧妙地做法,只要前一个不是一样的必然要刷一次,保证是最 ...

  2. Core Animation2-CABasicAnimation

    CABasicAnimation是CAPropertyAnimation的子类,使用它可以实现一些基本的动画效果,它可以让CALayer的某个属性从某个值渐变到另一个值.下面就用CABasicAnim ...

  3. lintcode:最小编辑距离

    最小编辑距离 给出两个单词word1和word2,计算出将word1 转换为word2的最少操作次数. 你总共三种操作方法: 插入一个字符 删除一个字符 替换一个字符 样例 给出 work1=&quo ...

  4. 图片bmp格式转换为jpg格式

    一下代码经过个人测试,可用 注意:将jpg格式的图片重命名为bmp格式,在该代码中是不能转换的,会报空值异常!而且IE10是显示不了这样的图片的 import java.awt.Image; impo ...

  5. 控制台console输出信息原理理解

    Eclipse控制台输出信息的控制 标签: Eclipse控制台输出信息 2015-01-02 14:11 22454人阅读 评论(1) 收藏 举报  分类: Some Tips(15)  版权声明: ...

  6. Hadoop基础教程-运行环境搭建

    一.Hadoop是什么 一个分布式系统基础架构,由Apache基金会所开发.用户可以在不了解分布式底层细节的情况下,开发分布式程序.充分利用集群的威力进行高速运算和存储. Hadoop实现了一个分布式 ...

  7. VNC常用操作及常见问题解决办法汇总

    VNC登录用户缺省是root,但在安装oracle时必须用oracle用户的身份登录,下面我们就以oracle为例说明如何配置VNC,从而可以使用不同的用户登录到主机.步骤描述如下:    步骤一:修 ...

  8. 自适应高度的 textarea

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  9. Android 如何去除桌面上下边框暗度逐渐变暗的效果

    前言          欢迎大家我分享和推荐好用的代码段~~ 声明          欢迎转载,但请保留文章原始出处:          CSDN:http://www.csdn.net        ...

  10. R之批处理

    在linux下如何编写脚本调用R语言写的程序呢? R语言进行批处理有2种方式: R CMD BATCH --options scriptfile outputfile Rscript --option ...