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的 ...
随机推荐
- idea分支合并
1.切换到指定分支(例如dev) 2.点击master的merge进行合并 注意:最好删掉本地的master和dev然后重新拉下远程的master和dev生成最新的本地master和dev
- java UUID的解析与应用(转载)
原文链接:http://www.blogjava.net/feelyou/archive/2008/10/14/234320.html 讨论UUID的定义.分类.应用及生成工具. 什么是UUID? U ...
- iOS Dev (26) 初步了解下UIColor的最常用知识
作者:CSDN 大锐哥 地址:http://blog.csdn.net/prevention - 内置的颜色有啥? // Some convenience methods to create colo ...
- 用EasyClient开源项目采集Windows摄像头/麦克风的音视频进行RTSP直播
EasyClient是EasyDarwin开源流媒体团队开发的一款功能丰富的开源PC客户端项目,目前支持Windows.Android版本,后续将支持ios版本,其中Windows版本的EasyCli ...
- Delphi类的默认区域
//类中数据成员的排列顺序一般是: 字段.方法.属性 //访问权限区域的顺序一般是: 无限制区(默认 published) private protected public pub ...
- Mongoose学习(3)--设置环境变量
比如我一套代码数据库代码分为中文站和英文站,每个表中我都有一个site_code字段来区分, 两个站点部署在不同的人服务器,这个时候我们就用系统环境变量来区分, 下面直接在mac下设置环境变量 vim ...
- [Java SE] 字符串连接
Java 支持多种字符串连接方式,总结如下: package cn.spads.tool.string; import java.text.MessageFormat; /** * <b> ...
- h5 placeholder 设置无效
下面设置方式无效: ::-webkit-input-placeholder { /* WebKit browsers */ color: #999; } :-moz-placeholder { /* ...
- 扩散(diffusion)和弥散(dispersion)有什么区别
作者:谢易正链接:https://www.zhihu.com/question/23914350/answer/177359196来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...
- HTML(DOM)与JavaScript嵌套数组之间相互转换
html2ja:将html目标元素解析为JavaScript数组字面量,每项的值为tagName, className, id等CSS选择器组合: showJa:将html2ja生成的数组缩进格式化显 ...