【转载】多模式串匹配之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自动机也是扔一 ...
随机推荐
- H5图片压缩上传
1.所用到技术 HTML5 API:filereader.canvas 以及 formdata 目前来说,HTML5的各种新API都在移动端的webkit上得到了较好的实现.本次使用到的FileRea ...
- 生产者与消费者 代码实现 java
首先,我利用忙测试写出了第一次版本的代码 package How; //自写代码 缺陷 无法完全实现pv操作线程处于忙测试状态 public class bin_1_1 { public static ...
- Android文件数据存储
利用Shared Preference或者数据库来存储应用程序数据是一种好的做法,但有时可能仍然希望直接使用文件,而不是依赖于Android的管理机制:尤其是使用多媒体文件的时候. Android提供 ...
- NOIP复习篇
NOIP复习篇---枚举 --------------------------------------------------------------------------------------- ...
- BZOJ3022 : [Balkan2012]The Best Teams
将选手和询问按照年龄排序,即可去掉年龄的限制. 将所有选手按水平排序后维护线段树,显然最优解一定是从大到小贪心选择. 线段树上每个节点维护: $g[0/1]:r+1$不选/选的时候,$l$选不选. $ ...
- [P1441]砝码称重 (搜索+DP)
对于我这种蒟蒻,是很不错的一题了. dfs搜索当前状态 满足时DP 比较坑的地方就是起始的地方 我一开始从1开始,搜索写的是从0开始. 后来就统一用0开始的了. #include<bits/st ...
- ssm数据库异常问题
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.Reflecti ...
- 创建触发器(trigger)
创建触发器 DROP TRIGGER IF EXISTS `ins_table_name`; DELIMITER ;; CREATE TRIGGER `ins_table_name` AFTER IN ...
- sqlserver触发器insert,delete,update
Create Trigger [dbo].[upemployee_kefyu_sale] on [dbo].[employee] for update as if update(FullName) b ...
- 论文泛读:Click Fraud Detection: Adversarial Pattern Recognition over 5 Years at Microsoft
这篇论文非常适合工业界的人(比如我)去读,有很多的借鉴意义. 强烈建议自己去读. title:五年微软经验的点击欺诈检测 摘要:1.微软很厉害.2.本文描述了大规模数据挖掘所面临的独特挑战.解决这一问 ...