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

Aho_Corasick自动机(AC自动机)

时间:2015-04-03 21:01:50      阅读:134      评论:0      收藏:0      [点我收藏+]

标签:

首先,AC自动机不是Accept自动机,别以为把这段代码复制到OJ上就全都自动AC了……

其实这玩意是Aho-Corasick 造出来的,所以你懂的。
那么这玩意能干嘛咧?
•字符串的匹配问题
•多串的匹配问题※
看不懂吧?解释一下:
例如给几个单词 acbs,asf,dsef,再给出一个 很长的文章,acbsdfgeasf,问在这个文章中,总共出现了多少个单词,或者是单词出现的总次数。
怎么实现的呢,就是KMP+trie树。是以KMP为算法基础,trie为索引结构的东东。那它如何与kmp联系在一起?
•关键是在trie树上加了一种fail指针。
•Fail指针的用途:就像是kmp中的next的数组。
在字符串失配的时候确定转移的节点。AC难点就是指针的算法,看下面这么多图:
技术分享
 
技术分享
技术分享
技术分享
技术分享
技术分享
技术分享
技术分享
技术分享
技术分享
模板:
 1 struct Aho_Corasick{
 2     int ch[maxn][Sigc], ms;
 3     int val[maxn], f[maxn], len[maxn];
 4     int last[maxn];
 5     Aho_Corasick(){}
 6     void init(){
 7         ms = 0;
 8         memset(val, 0, sizeof(val));
 9         memset(ch, 0, sizeof(ch));
10         memset(f, 0, sizeof(f));
11         memset(last, 0, sizeof(last));
12         memset(len, 0, sizeof(len));
13         return ;
14     }
15     void insert(char* s, int v){
16         int cur = 0, i;
17         for(i = 0; s[i] != \0; i ++){
18             int c = s[i] - 0;
19             if(!ch[cur][c]) ch[cur][c] = ++ ms; // 1
20             cur = ch[cur][c];
21         }
22         val[cur] = v; len[cur] = i;
23         return ;
24     }
25     void make_fail(){
26         queue<int> Q;
27         for(int i = 0; i < Sigc; i ++) if(ch[0][i]) Q.push(ch[0][i]);
28         while(!Q.empty()){
29             int x = Q.front(); Q.pop();
30             for(int c = 0; c < 2; c ++){
31                 int v = ch[x][c];
32                 if(!v) { ch[x][c] = ch[f[x]][c]; continue; }
33                 Q.push(v);
34                 int cur = f[x];
35                 while(cur && !ch[cur][c]) cur = f[cur];
36                 f[v] = ch[cur][c];
37                 last[v] = val[f[v]] ? f[v] : last[f[v]];
38             }
39         }
40         return ;
41     }
42 };

 

Aho_Corasick自动机(AC自动机)

标签:

原文地址:http://www.cnblogs.com/chxer/p/4390976.html

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