AC自动机---个人总结
比较好的 AC自动机算法详解..
【转】http://www.cppblog.com/mythit/archive/2009/04/21/80633.html
个人总结:【图是盗用的..】
ac自动机是用来求出:给出n个单词,和一篇文章arr[],问arr中出现了多少个单词..
第一步:根据给出的n个单词构造一棵字典树
第二步:根据字典树完成失配指针
第三步:枚举文章中的每个字符,并根据拥有了失配指针的字典树 查找 出现的单词个数
以单词:say she shr he her 文章:yasherhs 举例:
第一步:根据给出的n个单词构造一棵字典树
const int kind = ;
struct node{
node *fail; //失败指针
node *next[kind]; //Tire每个节点的个子节点(最多个字母)
int count; //是否为该单词的最后一个节点
node(){ //构造函数初始化
fail=NULL;
count=;
memset(next,NULL,sizeof(next));
}
}*q[]; //队列,方便用于bfs构造失败指针
char keyword[]; //输入的单词
char str[]; //模式串
int head,tail; //队列的头尾指针
结构体
void insert(char *str,node *root){
node *p=root;
int i=,index;
while(str[i]){
index=str[i]-'a';
if(p->next[index]==NULL) p->next[index]=new node();
p=p->next[index];
i++;
}
p->count++; //在单词的最后一个节点count+1,代表一个单词
}
构造字典树
第二步:根据字典树完成失配指针
<结果是 (she)每一个字符(s,h,e)都会指向自己上一个字符(root,s,h)的失配指针(root,root,root->h)后的和当前字符匹配((如果没有则指向root)root, root->h, root->h->e)的字符>
即结果是保证树中的节点(node)会指向拥有相同字符串(parents->..->node = root->..->node',parents表示某个祖先节点,node'表示相同字符节点)的枝桠(没有则指向root)
void build_ac_automation(node *root){
int i;
root->fail=NULL;
q[head++]=root;
while(head!=tail){
node *temp=q[tail++];
node *p=NULL;
for(i=;i<;i++){
if(temp->next[i]!=NULL){
if(temp==root) temp->next[i]->fail=root;
else{
p=temp->fail;
while(p!=NULL){
if(p->next[i]!=NULL){
temp->next[i]->fail=p->next[i];
break;
}
p=p->fail;
}
if(p==NULL) temp->next[i]->fail=root;
}
q[head++]=temp->next[i];
}
}
}
}
完成失配指针
第三步:枚举文章中的每个字符,并根据拥有了失配指针的字典树 查找 出现的单词个数 <cnt += node.cnt>
int query(node *root){
int i=,cnt=,index,len=strlen(str);
node *p=root;
while(str[i]){
index=str[i]-'a';
while(p->next[index]==NULL && p!=root) p=p->fail;
p=p->next[index];
p=(p==NULL)?root:p;
node *temp=p;
while(temp!=root && temp->count!=-){
cnt+=temp->count;
temp->count=-;
temp=temp->fail;
}
i++;
}
return cnt;
}
查找
查找方法是如果上一个字符的下一个字符和当前字符匹配,则加上node.cnt,并不断按照失配指针查找出现的单词,不断加上node.cnt
失配,则根据失配指针去找可能匹配的出现的单词,找到则加上node.cnt
AC自动机---个人总结的更多相关文章
- 基于trie树做一个ac自动机
基于trie树做一个ac自动机 #!/usr/bin/python # -*- coding: utf-8 -*- class Node: def __init__(self): self.value ...
- AC自动机-算法详解
What's Aho-Corasick automaton? 一种多模式串匹配算法,该算法在1975年产生于贝尔实验室,是著名的多模式匹配算法之一. 简单的说,KMP用来在一篇文章中匹配一个模式串:但 ...
- python爬虫学习(11) —— 也写个AC自动机
0. 写在前面 本文记录了一个AC自动机的诞生! 之前看过有人用C++写过AC自动机,也有用C#写的,还有一个用nodejs写的.. C# 逆袭--自制日刷千题的AC自动机攻克HDU OJ HDU 自 ...
- BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2545 Solved: 1419[Submit][Sta ...
- BZOJ 3172: [Tjoi2013]单词 [AC自动机 Fail树]
3172: [Tjoi2013]单词 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 3198 Solved: 1532[Submit][Status ...
- BZOJ 1212: [HNOI2004]L语言 [AC自动机 DP]
1212: [HNOI2004]L语言 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1367 Solved: 598[Submit][Status ...
- [AC自动机]【学习笔记】
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)To ...
- AC自动机 HDU 3065
大概就是裸的AC自动机了 #include<stdio.h> #include<algorithm> #include<string.h> #include< ...
- AC自动机 HDU 2896
n个字串 m个母串 字串在母串中出现几次 #include<stdio.h> #include<algorithm> #include<string.h> #inc ...
- 【BZOJ-3881】Divljak AC自动机fail树 + 树链剖分+ 树状数组 + DFS序
3881: [Coci2015]Divljak Time Limit: 20 Sec Memory Limit: 768 MBSubmit: 508 Solved: 158[Submit][Sta ...
随机推荐
- VC2008下使用OpenSSL 1.0.0g(免编译)
OpenSSL整个软件包大概可以分成三个主要的功能部分:密码算法库.SSL协议库以及应用程序. 官网:http://www.openssl.org/OpenSSL for Windows:http:/ ...
- Spring3表达式语言(SpEL)学习笔记
最新地址请访问:http://leeyee.github.io/blog/2011/06/19/spring-expression-language Spring Excpression Langua ...
- Android NDK 简单介绍、工具安装、环境配置
NDK全称:Native Development Kit. 1.NDK是一系列工具的集合. * NDK提供了一系列的工具,帮助开发人员高速开发C(或C++)的动态库,并能自己主动将so和java应用一 ...
- 使用JDBC处理数据库大容量数据类型
在本文将介绍如何使用JDBC操作MySQL数据库对于大容量数据类型的读取.在之前的博客中已经介绍了如何使用JDBC来操作数据库对各种数据的增删改查,那么大容量数据类型的数据操作又为何不同呢. 原因在于 ...
- Servlet过滤器——创建过滤器
1.概述 介绍如何创建一个过滤器,并使用过滤器在打开页面的同时输出信息,此功能是由过滤器处理完成的. 2.技术要点 Serlvet过滤器实现了Filter接口,在Filter接口中定义了以下几个方法: ...
- android 请求网络 和 httpclient的使用上传下载
访问网络最主要的也就是 http协议了. http协议很简单,但是很重要. 直接上代码了,里面都是1个代码块 代码块的,用哪一部分直接拷出去用就好了. 1.访问网络用 get 和 post 自己组拼 ...
- Android生存指南:Eclipse快捷键
天天使用的东西,可能是由于太习惯它了吧.总忘记学习怎样高效的使用它.正的谓磨刀不误劈柴功,找时间好好磨磨刀.于人于已都是有优点的.效率高了,多省出点时间去干自己真正喜欢干的事情吧. 精进Eclipse ...
- Linux下select, poll和epoll IO模型的详解
http://blog.csdn.net/tianmohust/article/details/6677985 一).Epoll 介绍 Epoll 可是当前在 Linux 下开发大规模并发网络程序的热 ...
- maven的命令使用笔记
(1)创建web项目mvn archetype:create -DgroupId=com.mycompany.webapp -DartifactId=myweb -DarchetypeArtif ...
- setenv 和 set
setenv 和 set 是在csh系列的命令,当然bash中也有set,还是有出入的. set 是对当前进程有效,不会传递给子进程 setenv 不仅对当前进程有效,也会传递给子进程. 语法 ...