【转载】多模式串匹配之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:

附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自动机也是扔一 ...
随机推荐
- 数据仓库分层ODS DW DM 主题 标签
数据仓库知识之ODS/DW/DM - xingchaojun的专栏 - CSDN博客 数据仓库为什么要分层 - 晨柳溪 - 博客园 数据仓库的架构与设计 - Trigl的博客 - CSDN博客 数据仓 ...
- Python3基础-高级用法
写在前面:本文主要是python高级练习部分,介绍了一些高级用法,这些都是零散的小知识,这些可以与函数式编程合在一起使用. 函数式编程1:Python中提供的函数式编程主要有: map(函数,可迭代式 ...
- 详解~实现Runnable方法创建线程之为什么要将Runnable接口的子类对象传递给Thread的构造函数
/** * @author zhao * @TIME 0419 22:56 End *定义线程的第二种方法:实现Runnable接口(不考虑安全问题) *步骤:1,定义一个子类实现Runnable接口 ...
- (Android系统目录结构)目录预览
Android系统进入设备后,查看根目录下文件系统,如下: 重要目录和文件说明:mnt 挂载点目录etc 系统主要配置文件system Android 系统文件sys Linux 内核文件proc 运 ...
- MySQL连接缓慢,打开缓慢原因
问题状况:最近由于服务器变换了网段,导致IP地址变换,变化后使用MySQL客户端连接MySQL服务器和在客户端中打开表的速度非常慢(无论表的大小),甚至连接超时,但是直接登录到服务器在本地连接MySQ ...
- Systick时钟定时
主函数 /* Note:Your choice is C IDE */ #include "stdio.h" #include "led.h" void mai ...
- [AMPPZ2014]Jaskinia
[AMPPZ2014]Jaskinia 题目大意: 一个\(n(n\le3\times10^5)\)的树,\(m(m\le3\times10^5)\)个约束条件\((a_i,b_i,d_i)\).请你 ...
- [CC-BLREDSET]Black and Red vertices of Tree
[CC-BLREDSET]Black and Red vertices of Tree 题目大意: 有一棵\(n(\sum n\le10^6)\)个结点的树,每个结点有一种颜色(红色.黑色.白色).删 ...
- js 倒计时10s
<button id="send">允许点击</button> var wait = 10; function time(o){ if(wait==0){ ...
- 论文泛读:Click Fraud Detection: Adversarial Pattern Recognition over 5 Years at Microsoft
这篇论文非常适合工业界的人(比如我)去读,有很多的借鉴意义. 强烈建议自己去读. title:五年微软经验的点击欺诈检测 摘要:1.微软很厉害.2.本文描述了大规模数据挖掘所面临的独特挑战.解决这一问 ...