【转载】多模式串匹配之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自动机也是扔一 ...
随机推荐
- BZOJ.1178.[APIO2009]会议中心(贪心 倍增)
BZOJ 洛谷 \(Description\) 给定\(n\)个区间\([L_i,R_i]\),要选出尽量多的区间,并满足它们互不相交.求最多能选出多少个的区间以及字典序最小的方案. \(n\leq2 ...
- 合并排序 java
java 实现合并排序 package How; import java.io.BufferedReader; import java.io.BufferedWriter; import java. ...
- Shell脚本笔记(五)Shell函数
Shell函数 1.定义语法 标准写法: funciton funName () { order....... return n } 简化写法1: funciton funName { order.. ...
- (转)我是一个java class
前言:本文主要想讲一下Java虚拟机的故事, 可能有点偏门,不妥之处欢迎留言交流. 第一回 陌生警察 我出生在C盘下面一个很深层次的目录下, 也不知道是谁把我放到这里的. 我一直在睡觉,外边的日出日落 ...
- BZOJ2689 : 堡垒
问题等价于每个三角形里至少选择两个点. 考虑拓扑,每次取出度数为$2$的点$x$,代表一个只与最多一个三角形相邻的三角形$(x,y,z)$. 如果$x$已选,那么$(x,y)$以及$(x,z)$都已经 ...
- 部署wepy框架开发微信小程序
我用的是yarn,如果你使用的是npm,也可以 首先需要安装wepy命令行工具 npm install wepy-cli -g 然后在选定的位置使用脚手架工具创建wepy项目 wepy init st ...
- redis:set集合类型的操作(无序集合)
1. set集合类型的操作(无序集合) 集合具有无序性(没有顺序).确定性(描述是确定的).唯一性(没有重复的元素) 1.1. sadd key member [member ...] 语法:sadd ...
- Vue(九)小案例 - 百度搜索列表(跨域)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- nodeJs --- web服务器创建
一.下载nodeJs http://nodejs.cn/download/ 根据自己的情况选择下载 然后在命令行中输入 node -v 看是否安装成功 (下载node时,会把npm包处理工具一起下) ...
- week 10 blog
一.Iterations : 1.do...while : 创建执行指定语句的循环,直到测试条件评估为false.在执行语句后评估条件,导致指定语句至少执行一次. 例子:在以下示例中,do...而循环 ...