AC自动机学习笔记

文不达意,口齿不清,思想混乱,令人喷饭。(估计只有我自己才能看懂我在说什么)简书没有mathjax公式没法愉快显示

AC自动机(Aho-Corasick Automaton)是一个依次输入一个字符串S的各个字符,仅当AC自动机中保存的字符串出现在当前串S当中时,进入合法状态的自动机。AC自动机被构建在一棵Trie树上。我们可以像使用KMP算法时一样,对节点构造Fail指针,实现线性时间复杂度的字符串匹配功能。

基础内容

AC自动机被构建在Trie树上,节点有Fail指针。考虑Fail指针的性质,Fail指针只有可能是如下几种情况中的一种:

  1. Fail指向Trie树的根节点
  2. Fail指向父节点开始的由Fail指针构成的链上某个节点的子节点

如何理解这条性质呢?当Trie树上同时有串ABCE和BCD,对于目标串ABCD进行字符串匹配的时候,AC自动机读入目标串中D的时候,发现和ABCE中的E不同,于是跳转到BCD中的D进行匹配。所以除了父节点的Fail指针指向根节点的情况外,节点的Fail指针满足上面的性质。于是有了构造Fail指针的办法:

/**
 * 约定:
 * CodeSet: 字符集,比如字母就是'a'~'z'
 * trie[u][i]: Trie树的边,u为节点编号,i为下一个字符,我们将一些额外的边(匹配之用)也会存进去
 * fail[u]: 失败指针,指向一个节点编号
 * root: 根节点编号,这里设置为0
 */
void makeFail(int u) {
  for (int i: codeSet) {
    if (trie[u][i]!=null) {
      int tmp=fail[u];
      while (tmp!=root&&trie[tmp][i]==null)
        tmp=fail[tmp];
      fail[trie[u][i]]=(u==root)?0:trie[tmp][i];
    }else {
      trie[u][i]=trie[fail[u]][i];      // 将不存在的子节点指向fail指针引导的状态
    }
  }
}

构造Fail指针需要遵从一定的顺序,显然DFS是不可以的。因为搜寻Fail指针的时候,有的节点(例如相邻子树上的节点)Fail指针没有计算出来,所以无法推算。在这种时候应当用BFS进行搜寻。

在上面构建Fail指针的时候我们还进行了另外一种操作:就是将”不存在的子节点“指向了Fail指针引导的子节点。在这样的一张有向图上我们就可以轻松地进行字符串匹配了。

字符串匹配

就像KMP算法一样,AC自动机对字符串的匹配也是逐个读入字符,比对并进行状态转移(在上文提到的生成的有向图中)。当遇到合法节点的时候,我们进行计数。下面看这样的例子:在ABCDEF中查找ABC和BC的过程

  1. 依次读入ABC,AC自动机从根结点开始由A->B->C进行转移,我们发现ABC被成功匹配了。当读取D的时候,状态被转移到了根节点,因为没有字符能和D匹配
  2. 直到读完原字符串为止

问题:BC没有被匹配到。实际上在进入合法节点的时候,合法节点Fail指针形成的链上,所有的合法节点均被匹配上了。实际统计匹配成功数时,我们可以只在该节点上计数。在统计完毕之后,将Fail指针形成的树做一次树形dp:节点的匹配数等于子树根节点匹配数之和来计算总匹配数。

题目

AC自动机的题目形式相对固定,虽然不会出特别裸的字符串匹配题目。

AC自动机在ACM赛场上出现一般会作为引出题目的状态转移、或者模型的工具。AC自动机的作用可以归结如下:

  1. 字符串匹配(HDU3065)
  2. 字符串计数
  3. 字符串构造(引出模型)

HDU5955 一个骰子不停的扔,扔出谁的目标序列谁就赢了,问:每个人获胜的概率。其中每个人对应一种目标序列(由1~6中的整数构成,且一局游戏中每个人的序列长度相等而不同)。

对所有人的获胜序列构造AC自动机。AC自动机中可以得到扔骰子的状态转移过程:实际上AC自动机中某个节点包含了之前扔的几次的信息(比如说从Trie树的根节点到该节点路径上的字符构成的串,这些信息往往很有用;又比如说节点是否是游戏的终止状态——最后几次的结果和某个人的串对应,游戏结束)。对于自动机中某个节点u,它能转移到的节点(后继)v_i一共有6个(很显然扔一个立方体骰子能产生6个不同的数字之一),到达该节点的概率就等于sum_{1}^{6}P(v_i)/6。根据这个构造出增量矩阵A:AC自动机中有边u->v(u不是游戏结束状态),那么u行v列被设置为1/6。假设答案是b(n维列矩阵,记录了自动机每个节点状态的概率), 初始序列是x(除了0节点概率为1之外其它都是0)。有

b=sum_{i=1}{inf}(Ai)x

当上式收敛时,将它改写为b=(E-A)^{-1}x,即(E-A)b=x,接下来的任务就是用高斯消元求解b。b中所有结束状态的概率即为所求答案。

很可惜在下并没有弄清楚题目背后的数学原理

POJ2778 有m种DNA序列是有疾病的,问有多少种长度为n的DNA序列不包含任何一种有疾病的DNA序列。(仅含A,T,C,G四个字符)

  1. m=4,n=3,{“AA”,”AT”,”AC”,”AG”},答案为36,表示有36种长度为3的序列可以不包含疾病
  2. 疾病字符串最多10个,且长度<=10

很惭愧……等我研究懂了再说

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • 归去来兮。 1.1 说明 本篇为《挑战程序设计竞赛(第2版)》[http://www.ituring.com.cn...
    尤汐Yogy阅读 14,270评论 0 160
  • 类似于week2,3;然后这一节题目说是Trie图,其实用AC自动机更容易搜出来结果。对于一个M<=10^6的字符...
    vaisy阅读 199评论 0 0
  • 1 序 2016年6月25日夜,帝都,天下着大雨,拖着行李箱和同学在校门口照了最后一张合照,搬离寝室打车去了提前租...
    RichardJieChen阅读 5,071评论 0 12
  • 远去的时光留下了 一路风尘的脚印 年少轻狂的人儿背上了遗憾 走过桃园看那花儿开 精气神十足 来到梨园满眼的雪白 是...
    马吉祥阅读 318评论 0 1
  • 2015年9.2-9.5我去了色达,去看红房子---五明佛学院。 9.2下午七点,集合,第一次跟户外团出行。第一次...
    木鱼and咸鱼阅读 340评论 2 1