【转载】多模式串匹配之AC自动机
原文地址:https://www.cnblogs.com/codeape/p/3845375.html
一、概述
二、AC算法思想

图2.1

图2.2

图2.3

图2.4

图2.5

图2.6
三、字典树tire的构造

图3.1
四、搜索路径的确定
附录:
附1:
图 附1.1附2:AC算法的伪代码实现描述
q := 0; // initial state (root)
for i := 1 to m do
while g(q,T) = NULL do
q := f(q); // 回溯
q := g(q,T); // 前进
node:=q;
while(node!=root){
if flag(node) exist ; then print i, out(node);
node = f(node); //查找回溯节点
}
end for;
附3:
/*
程序说明:多模式串匹配的AC自动机算法
自动机算法可以参考《柔性字符串匹配》里的相应章节,讲的很清楚
*/include <stdio.h>
include <string.h>
const int MAXQ = 500000+10;
const int MAXN = 1000000+10;
const int MAXK = 26; //自动机里字符集的大小
struct TrieNode
{
TrieNode* fail;
TrieNode* next[MAXK];
bool danger; //该节点是否为某模式串的终结点
int cnt; //以该节点为终结点的模式串个数
TrieNode()
{
fail = NULL;
memset(next, NULL, sizeof(next));
danger = false;
cnt = 0;
}
}*que[MAXQ], *root;
//文本字符串
char msg[MAXN];
int N;
void TrieInsert(char *s)
{
int i = 0;
TrieNode *ptr = root;
while(s)
{
int idx = s-'a';
if(ptr->next[idx] == NULL)
ptr->next[idx] = new TrieNode();
ptr = ptr->next[idx];
i++;
}
ptr->danger = true;
ptr->cnt++;
} void Init()
{
int i;
char s[100];
root = new TrieNode();printf("输入模式串数量:");
scanf("%d", &N);
for(i = 0; i < N; i++)
{
printf("输入第%d个模式串(共%d个):",i,N);
scanf("%s", s);
TrieInsert(s);
}
}
void Build_AC_Automation()
{
int rear = 1, front = 0, i;
que[0] = root;
root->fail = NULL;
while(rear != front)
{
TrieNode *cur = que[front++];
for(i = 0; i < 26; i++)
if(cur->next != NULL)
{
if(cur == root)
cur->next->fail = root;
else
{
TrieNode *ptr = cur->fail;
while(ptr != NULL)
{
if(ptr->next != NULL)
{
cur->next->fail = ptr->next;
if(ptr->next->danger == true)
cur->next->danger = true;
break;
}
ptr = ptr->fail;
}
if(ptr == NULL) cur->next->fail = root;
}
que[rear++] = cur->next;
}
}
}
int AC_Search()
{
int i = 0, ans = 0;
TrieNode *ptr = root;
while(msg)
{
int idx = msg-'a';
while(ptr->next[idx] == NULL && ptr != root) ptr = ptr->fail;
ptr = ptr->next[idx];
if(ptr == NULL) ptr = root;
TrieNode *tmp = ptr;
while(tmp != NULL )&& tmp->cnt != -1)
{
ans += tmp->cnt; //统计文本中出现过的不同模式串数量
tmp->cnt = -1;//对于每个模式串的出现只计算一次,如统计所有出现则应注释该行
tmp = tmp->fail;
}
i++;
}
return ans;
}
int main()
{
int T;
printf("输入测试次数:");
scanf("%d", &T);
while(T--)
{
Init();
Build_AC_Automation();
//文本
printf("输入匹配文本:");
scanf("%s", msg);
printf("%dn", AC_Search());
}
getchar();
return 0;
}
下载:
点击下载此文件【转载】多模式串匹配之AC自动机的更多相关文章
- hdu2457(最少替换多少个字符使主串不包含模式串)ac自动机+dp
题:http://acm.hdu.edu.cn/showproblem.php?pid=2457 题意:给定n个模式串,给定一个主串,问最替换掉多少个字符使主串不包含模式串或输出“-1”表示没有可行的 ...
- UVA 11019 Matrix Matcher ( 二维字符串匹配, AC自动机 || 二维Hash )
题目: 传送门 题意: 给你一个 n * m 的文本串 T, 再给你一个 r * c 的模式串 S: 问模式串 S 在文本串 T 中出现了多少次. 解: 法一: AC自动机 (正解) 670ms 把模 ...
- Aho-Corasick 多模式匹配算法、AC自动机详解
Aho-Corasick算法是多模式匹配中的经典算法,目前在实际应用中较多. Aho-Corasick算法对应的数据结构是Aho-Corasick自动机,简称AC自动机. 搞编程的一般都应该知道自动机 ...
- HDU2222 Keywords Search(AC自动机模板)
AC自动机是一种多模式匹配的算法.大概过程如下: 首先所有模式串构造一棵Trie树,Trie树上的每个非根结点都代表一个从根出发到该点路径的字符串. 然后每个结点都计算出其fail指针的值,这个fai ...
- 算法笔记--字典树(trie 树)&& ac自动机 && 可持久化trie
字典树 简介:字典树,又称单词查找树,Trie树,是一种树形结构,是哈希树的变种. 优点:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较. 性质:根节点不包含字符,除根节点外每一个 ...
- hdu1686 Oulipo KMP/AC自动机
The French author Georges Perec (1936–1982) once wrote a book, La disparition, without the letter 'e ...
- 咕咕(数位dp+AC自动机)
咕咕(数位dp+AC自动机) 若一个字符串的字符集合是0~m-1,那么称它为m进制字符串.给出n个m进制字符串\(s_i\),每个字符串的权值为\(v_i\).对于另一个m进制字符串\(S\),设\( ...
- 【复习笔记】重习 AC 自动机
发现已经忘了许多....于是复习一下 基础要点概况 AC 自动机基于 Trie 树 的结构,即构建 AC 自动机前需要先建 Trie. 一个状态中除了转移 \(\delta\) 之外还有失配指针 \( ...
- AC自动机
AC自动机,全称Aho-Corasick自动机.如果没记错的话好像就是前缀自动机. 其实AC自动机就是KMP上树的产物.理解了KMP,那AC自动机应该也是很好理解的. 与KMP类似,AC自动机也是扔一 ...
随机推荐
- Stm32常见英文缩写
Stm32常见英文缩写 https://wenku.baidu.com/view/4b9c2eee5022aaea998f0f5b.html STM32嵌入式开发常见缩写 https://wenku. ...
- 第一本docker书,,持续更新中
1.查看应用是否在docker中部署成功 需要确认curl已安装 whereis curl sudo apt-get -y install curl curl localhost:8081 如果成 ...
- [ZJOI2013]K大数查询
Description: 给定一个序列,支持两种操作 1.在[L,R]的每个位置上加上一个数 (注意一个位置上有多个数) 2.查询[L,R]上所有数中的第K大 Hint: \(n,m<=5e4\ ...
- CY7C68013 USB接口相机开发记录 - 第四天:上位机编写1
前面学习了USB相机硬件固件.设备驱动,可以实现USB设备识别.数据发送的功能.然后,非常重要的一部分,USB设备发出的数据,我要怎么接受,怎么查看发送的数据是否是正确的.网上百度了下,大部分人都使用 ...
- pycharm实现sublime的显示效果,很惊艳哦
收到https://github.com/simoncos/pycharm-monokai链接中的指引 下载箭头所指的文件,然后按照 PyCharm -> File -> Settings ...
- css解决滚动弹出层里边的滚动条时带动了整个页面滚动的问题
之前一个朋友问我说他的一个弹出层在弹出后,上下滑动弹出层或遮罩层,结果遮罩层下边的整个页面(页面超出了一屏)也跟着滚动了,他说他不想要这样的效果,我说你把弹出层和遮罩层的position:fixed设 ...
- GMA Round 1 极坐标的愤怒
传送门 极坐标的愤怒 我也想被积分啊!可是为什么你们从来不知道我的心意!——极坐标 愤怒会夺走理智,哪怕是被迫的也好,请为极坐标方程$r=t$(也写作$ρ=θ$)积分吧. 为了考验你的忠诚,你需要回答 ...
- JAVA自学笔记20
JAVA自学笔记20 1.递归: 1)方法定义中定义中调用方法本身的现象 2)要有出口,否则就是死递归 次数不能太多.否则内存将溢出 构造方法不能递归使用 //斐波那契数列:1,1,2,3,5,8,1 ...
- 2017年50道Java线程面试题
下面是Java线程相关的热门面试题,你可以用它来好好准备面试. 1) 什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理器编 ...
- Android 使用easeui 3.0 集成环信即时通讯 我踩过的坑
0.关于注冊账号就不用说了. 1.创建应用.获取appkey 0.创建应用 1.填写信息 2.获取appkey 2.集成 0.首先新建一个project 1.这里主要介绍使用easeui来集成环信的即 ...