【暑假】[实用数据结构] AC自动机
2024-08-28 19:10:15
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]];
}
}
} };
最新文章
- 原生Ajax总结
- 孙鑫MFC学习笔记10:画图/贴图
- pyqt5界面与逻辑分离--信号槽的装饰器实现方式
- Windows-003-桌面无显解决方法
- idea配置jetty服务器,通过mvn实现
- Java基础学习笔记二十三 Java核心语法之反射
- GitHub for Windows离线安装包
- opencv2\core\cuda.hpp(106): error C2059: 语法错误:“常量”
- wampserver安装
- https协议的接口测试
- BOM进IN_BOM_HEADER表后被过滤掉
- 音频播放 音乐 MediaPlayer
- 一步一步学android控件(之六) —— MultiAutoCompleteTextView
- Django ImportError 模块路径正确,且将文件夹设置为Source Root
- check the manual that corresponds to your MySQL server version for the right syntax to use near &#39;desc
- sql server中的日期函数
- 遇到OutOfMemoryException异常了
- LTC 钱包部署
- HDU 4417.Super Mario-可持久化线段树(无修改区间小于等于H的数的个数)
- iOS开发必备指南合集之游戏接入GameCenter 指南
热门文章
- 1588: [HNOI2002]营业额统计 - BZOJ
- BZOJ 1697: [Usaco2007 Feb]Cow Sorting牛排序
- Clojure语法学习-循环
- TaskTracker执行map或reduce任务的过程(二)
- nginx上用fastcgi配置python环境
- jmeter summariser(命令行执行时的输出) 、查看结果树等结果中文乱码
- BZOJ 2553 禁忌
- jquery的ajax和原始的ajax这两种方式的使用方法
- 【Java】JTable组件的构造函数和设置列宽
- 函数(Functions)