HDU3065【AC自动机-AC感言】
Fourth AC zi dong ji(Aho-Corasick Automation) of life
9A(其实不止交了10发...) 感言:
一开始多组数据这种小数据还是...无伤大局,因为改完以后还是wa...
一:
最后发现是wa在构造fail指针的时候在建立临时指针查询有没有匹配到的fail,在没有匹配到的时候,结点的fail的指针要指向根。
二(重要感言):
在查询时,往上回溯fail指针的时候,fail指针是一定会最终回溯到根的,而且,比如当前查询到的主串是ABCDEF,fail指针可能会一直传递最终到根,但是并不是都有效啊!这里还要注意,fail指针传递过去,找到的是子串,还是本来那个串的后缀串,为什么说是子串:如果有模式串ABCD,ABCDEF,主串是ACBDEF,主串到D的时候已经处理掉了ABCD,这个情况下是不会用到fail指针的功效了,或者这里没有有效的后缀串;什么时候会用fail指针呢,如果有模式串CD,BCD,ABCDEF,主串是ACBDEF,那么在主串到D的时候会通过fail指针找到BCD,然后在找到CD,所以我们能得出,fail指针的回溯,当前串(比如ABCD)最后那个D是一直不会变的,可以说fail指针都是D的fail指针!
三:
不要依赖模板...
推荐几个数据:
2
CC
AAA
ooxxCC%dAAAoen....ENDooxxCC%dAAAoen....ENDooxxCC%dAAAoen....END
2
ABCDE
BCD
ABCD
2
ABCDE
BCD
ABCDEF
//#include <bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<queue>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long LL; /*
题意:
求不同的病毒出现的次数,未出现的不需要输出
AAA其中AA出现2次;
思路:
那我存的应该是编号了,编号都不同。
*/ const int N=5e4+10; struct Trie
{
int id;
Trie *next[26],*fail;
};
Trie q[N],*root;
int tol,ans[1010],n;
char ss[1010][51]; Trie* Creat()
{
Trie *p;
p=&q[tol++];
p->fail=NULL;
p->id=0;
for(int i=0; i<26; i++)
p->next[i]=NULL;
return p;
} void Insert(char *str,int id)
{
Trie *p=root;
int index,len=strlen(str);
for(int i=0; i<len; i++)
{
index=str[i]-'A';
if(p->next[index]==NULL)
p->next[index]=Creat();
p=p->next[index];
}
p->id=id;
} void Build_Ac()
{
queue<Trie*>que;
que.push(root);
while(!que.empty())
{
Trie *p=que.front();que.pop();
for(int i=0; i<26; i++)
{
if(p->next[i]!=NULL)
{
if(p==root)
p->next[i]->fail=root;
else
{
Trie *temp=p->fail;
while(temp!=NULL)//找匹配的
{
if(temp->next[i]!=NULL) //找到
{
p->next[i]->fail=temp->next[i];
break;
}
temp=temp->fail;
}
if(temp==NULL) //如果没有找到匹配的,则fail指向根
p->next[i]->fail=root;
}
que.push(p->next[i]);
}
}
}
} char word[2000010];
void Query()
{
int res=0;
int index,len=strlen(word);
Trie *p=root; for(int i=0; i<len; i++)
{
if(!(word[i]>='A'&&word[i]<='Z')){
p=root;
continue;
}
index=word[i]-'A';
while(p->next[index]==NULL && p!=root)
p=p->fail;
p=p->next[index];
if(p==NULL)
p=root;
Trie *temp=p;
while(temp!=root) //回溯到根
{
ans[temp->id]++; //这里这样写没事,因为我不会用到id为0的,任他+
temp=temp->fail;
}
}
for(int i=1; i<=n; i++)
{
if(ans[i])
printf("%s: %d\n",ss[i],ans[i]);
}
} int main()
{
while(~scanf("%d",&n))
{
tol=0;
root=Creat();
for(int i=1; i<=n; i++)
{
ans[i]=0;
scanf("%s",ss[i]);
Insert(ss[i],i);
}
getchar();
Build_Ac();
gets(word);
Query();
}
return 0;
}
;
HDU3065【AC自动机-AC感言】的更多相关文章
- AC自动机(AC automation)
字典树+KMP 参考自: http://www.cppblog.com/mythit/archive/2009/04/21/80633.html ; //字典大小 //定义结点 struct node ...
- 从Trie谈到AC自动机
ZJOI的SAM让我深受打击,WJZ大神怒D陈老师之T3是SAM裸题orz...我还怎么混?暂且写篇`从Trie谈到AC自动机`骗骗经验. Trie Trie是一种好玩的数据结构.它的每个结点存的是字 ...
- 多模字符串匹配算法之AC自动机—原理与实现
简介: 本文是博主自身对AC自动机的原理的一些理解和看法,主要以举例的方式讲解,同时又配以相应的图片.代码实现部分也予以明确的注释,希望给大家不一样的感受.AC自动机主要用于多模式字符串的匹配,本质上 ...
- AC自动机详解(附加可持久化AC自动机)
AC自动机 AC自动机,说白了就是在trie树上跑kmp(其实个人感觉比kmp容易理解).是一种多匹配串,单个主串的匹配.概括来说,就是将多个匹配串构造一个trie树,对于每个trie树的节点构造nx ...
- 浅谈算法——AC自动机
在学习AC自动机之前,你需要两个前置知识:Trie树,KMP 首先我们需要明白,AC自动机是干什么的(用来自动AC的) 大家都知道KMP算法是求单字符串对单字符串的匹配问题的,那么多字符在单字符上匹配 ...
- T2 AC自动机
T2:AC自动机 (ac.cpp) 题目背景 YZD在每天学习20小时的勤奋研究下,终于开发出了AC自动机!但是,这台AC自动机有一些bug,比如两个部件之间经常会出一些莫名其妙的问题,所以他想要随时 ...
- [Alg] 文本匹配-多模匹配-AC自动机
1. 简介 AC自动机是一种多模匹配的文本匹配算法. 如果采用naive的方法,即依次比较文本串s中是否包含模式串p1, p2,...非常耗时.考虑到这些模式串中可能具有相同子串,可以利用已经比较过的 ...
- 【HDU3065】 病毒侵袭持续中(AC自动机)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...
- hdu3065 病毒侵袭持续中 AC自动机入门题 N(N <= 1000)个长度不大于50的模式串(保证所有的模式串都不相同), 一个长度不大于2000000的待匹配串,求模式串在待匹配串中的出现次数。
/** 题目:hdu3065 病毒侵袭持续中 链接:http://acm.hdu.edu.cn/showproblem.php?pid=3065 题意:N(N <= 1000)个长度不大于50的 ...
随机推荐
- 前端基础——CSS盒子模型
如今很多网页都是由很多个"盒子"拼接.嵌套而成,所以多少接触过网页设计的朋友一定都对CSS盒子模型有所了解. 为了更好的说明,先举个通俗的样例:在一个仓库中放了10个纸箱,每一个纸 ...
- php 中 isset 和empty 的区别
昨天终于开始学习php了,这个对于我来说听着很熟悉,但是学起来很陌生的东西,尤其是课上能听明白 但是真正写起了手生,都不知道手该往哪里放了,天哪~~~ 其中课上有讲到 isset和empty的区别,现 ...
- Spring中的JDBC操作
一.Spring模板JdbcTemplate 为了使 JDBC 更加易于使用, Spring 在 JDBC API 上定义了一个抽象层, 以此建立一个 JDBC 存取框架JdbcTemplate. 作 ...
- Hibernate的检索策略和优化
一.检索策略概述 当我们实现了一对多或者多对多的映射后,在检索数据库时需要注意两个问题: 1.使用尽可能小的内存:当 Hibernate 从数据库中加载一个客户信息时, 如果同时加载所有关联这个客户的 ...
- Hibernate中的Sesson操作
一.Session概述 Session是应用程序与数据库之间的一个会话,是Hibernate运作的中心,持久层操作的基础,相当于JDBC中的Connection.Session对象是通过Session ...
- C#实现(递归和非递归)高速排序和简单排序等一系列排序算法
本人由于近期工作用到了一些排序算法.就把几个简单的排序算法.想冒泡排序,选择排序,插入排序.奇偶排序和高速排序等整理了出来,代码用C#代码实现,而且通过了測试.希望能给大家提供參考. ...
- 软件版本GA,RC,alpha,beta含义
软件版本GA,RC,alpha,beta含义 (1)RC:(Release Candidate) Candidate是候选人的意思,用在软件上就是候选版本.Release.Candidate.就是发行 ...
- complex brain network
Organization, development and function of complex brain networks The Brain as a Complex System: Usin ...
- PYTHON 爬虫笔记三:Requests库的基本使用
知识点一:Requests的详解及其基本使用方法 什么是requests库 Requests库是用Python编写的,基于urllib,采用Apache2 Licensed开源协议的HTTP库,相比u ...
- Memory Notification: Library Cache Object loaded into SGA
问题现象: 数据库服务器可以ping通,但SSH连接不了:应用.plsqldeveloper 也都连接不了.事情到了这个地步,只能重启服务器. 服务器环境:oracle10.2.0.1 +rhel5. ...