Aho-Corasick自动机

 算法:

<功能>

AC自动机用于解决文本一个而模板有多个的问题。

AC自动机可以成功将多模板匹配,匹配意味着算法可以找到每一个模板在文本中出现的位置。

<解释>

KMP中对模板构造失配边,多模板每条模板独立构造失配边太过麻烦。

算法利用Trie+KMP中的失配边。insert(模板) 构造Trie+ getFail添加失配边->AC自动机的状态转移图。

匹配文本串text时只需要调用find,find依次匹配text中的每一个字符失败则沿着失配边走,在匹配路径上如果遇到单词结点(val != 0 )即相当于匹配成功。

但需要注意到:可能有作为当前后缀的单词已经成功匹配,所以需要加入后缀链接last[] 在每一个结点都要处理这种情况。last递推得到。

作者所给模板如下

 struct AhoCorasickAutomata {
int ch[MAXNODE][SIGMA_SIZE];
int f[MAXNODE]; // fail函数
int val[MAXNODE]; // 每个字符串的结尾结点都有一个非0的val
int last[MAXNODE]; // 输出链表的下一个结点
int cnt[MAXS];
int sz; void init() {
sz = ;
memset(ch[], , sizeof(ch[]));
memset(cnt, , sizeof(cnt));
ms.clear();
} // 字符c的编号
int idx(char c) {
return c-'a';
} // 插入字符串 v必须非0
void insert(char *s, int v) {
int u = , n = strlen(s);
for(int i = ; i < n; i++) {
int c = idx(s[i]);
if(!ch[u][c]) {
memset(ch[sz], , sizeof(ch[sz]));
val[sz] = ;
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u] = v;
ms[string(s)] = v;
} // 递归打印以结点j结尾的所有字符串
void print(int j) {
if(j) {
cnt[val[j]]++;
print(last[j]);
}
} // 在T中找模板
int find(char* T) {
int n = strlen(T);
int j = ; // 当前结点编号 初始为根结点
for(int i = ; i < n; i++) { // 文本串当前指针
int c = idx(T[i]);
while(j && !ch[j][c]) j = f[j]; // 顺着细边走 直到可以匹配
j = ch[j][c];
if(val[j]) print(j);
else if(last[j]) print(last[j]); // 找到了
}
} // 计算fail函数
void getFail() {
queue<int> q;
f[] = ;
// 初始化队列
for(int c = ; c < SIGMA_SIZE; c++) {
int u = ch[][c];
if(u) { f[u] = ; q.push(u); last[u] = ; }
}
// 按BFS顺序计算fail
while(!q.empty()) {
int r = q.front(); q.pop();
for(int c = ; c < SIGMA_SIZE; c++) {
int u = ch[r][c];
if(!u) continue;
q.push(u);
int v = f[r];
while(v && !ch[v][c]) v = f[v];
f[u] = ch[v][c];
last[u] = val[f[u]] ? f[u] : last[f[u]];
}
}
} };

最新文章

  1. 原生Ajax总结
  2. 孙鑫MFC学习笔记10:画图/贴图
  3. pyqt5界面与逻辑分离--信号槽的装饰器实现方式
  4. Windows-003-桌面无显解决方法
  5. idea配置jetty服务器,通过mvn实现
  6. Java基础学习笔记二十三 Java核心语法之反射
  7. GitHub for Windows离线安装包
  8. opencv2\core\cuda.hpp(106): error C2059: 语法错误:“常量”
  9. wampserver安装
  10. https协议的接口测试
  11. BOM进IN_BOM_HEADER表后被过滤掉
  12. 音频播放 音乐 MediaPlayer
  13. 一步一步学android控件(之六) —— MultiAutoCompleteTextView
  14. Django ImportError 模块路径正确,且将文件夹设置为Source Root
  15. check the manual that corresponds to your MySQL server version for the right syntax to use near &#39;desc
  16. sql server中的日期函数
  17. 遇到OutOfMemoryException异常了
  18. LTC 钱包部署
  19. HDU 4417.Super Mario-可持久化线段树(无修改区间小于等于H的数的个数)
  20. iOS开发必备指南合集之游戏接入GameCenter 指南

热门文章

  1. 1588: [HNOI2002]营业额统计 - BZOJ
  2. BZOJ 1697: [Usaco2007 Feb]Cow Sorting牛排序
  3. Clojure语法学习-循环
  4. TaskTracker执行map或reduce任务的过程(二)
  5. nginx上用fastcgi配置python环境
  6. jmeter summariser(命令行执行时的输出) 、查看结果树等结果中文乱码
  7. BZOJ 2553 禁忌
  8. jquery的ajax和原始的ajax这两种方式的使用方法
  9. 【Java】JTable组件的构造函数和设置列宽
  10. 函数(Functions)