HDU 2222 关键词查找
题目大意:给出一篇文章,长度最多1000000,若干个关键词,关键词有可能重复。关键词不超过10000,每个关键词不超过50个字符。请问该文章包含多少个关键词。
这是AC自动机的入门题。首先将关键词分别插入到一棵trie树中,对每个关键词的对应的结束节点设置一个标记;第二步设置trie树中节点的fail指针。每个节点u都得有fail指针,指向某一个节点v,表示当u无法继续往下匹配时,u应该跳转的节点。节点u与v的字符相同,且根到v的字符串为根到u的字符串的最长后缀。如果u没有找到对应的v,则u的fail指针指向root。root的fail指针指向自身;第三步则是查询。查询时从根节点开始。每次根据当前的字符在当前节点的儿子中找到对应节点,如果没有找到,则跳转到当前节点的fail指针处,一直要找到某个节点,在它儿子中存在和当前字符匹配的节点,然后继续往下。当然如果到了根节点也没有找到,则查找下一个字符了。这里要注意的是,即使当前节点可以继续往下匹配,在当前节点往下匹配之前,我们需要另外拿一个指针,从当前节点出发,通过fail指针往上遍历,筛选是否有结束节点。因为有些关键词可能是当前节点到根的字符串的后缀。每个节点被筛选后可以做一个标记,下次筛选到这里时可以提前退出了。这样可以保证每个节点最多被筛选一次。
具体见代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAXC 26
struct node
{
int cnt,fail,nxt[MAXC];
}trie[];
int root,tot=,myq[],res=,T,n,head,tail;
char artical[],word[];
void insert(int r,char *s)
{
int len=strlen(s),val;
for(int i=;i<len;i++)
{
val=s[i]-'a';
if(trie[r].nxt[val]==)
trie[r].nxt[val]=++tot;
r=trie[r].nxt[val];
}
trie[r].cnt++;
}
void build(int r)
{
trie[r].fail=r;
myq[tail++]=r;
while(head<tail)
{
r=myq[head++];
for(int i=;i<MAXC;i++)
{
int ch,p;
if(ch=trie[r].nxt[i])
{
myq[tail++]=ch;
for(p=trie[r].fail;p!=root&&trie[p].nxt[i]==;p=trie[p].fail);
int tmp=trie[p].nxt[i];//tmp可能为空,因为p可能为根节点。
if(tmp&&tmp!=ch)trie[ch].fail=tmp;//防止ch的fail指针指向自己
else trie[ch].fail=root;
}
}
}
}
void query(int r,char *s)
{
int len=strlen(s),val;
for(int i=;i<len;i++)
{
val=s[i]-'a';
while(r!=root&&trie[r].nxt[val]==)
r=trie[r].fail;
r=trie[r].nxt[val];
if(r==)r=root;
for(int temp=r;temp!=root;temp=trie[temp].fail)//查询时要另一个指针从当前节点通过fail往上找。
{
if(trie[temp].cnt==-)break; //凡是找过的节点cnt设置为-1.所以遇到,可以提前退出。
res+=trie[temp].cnt;
trie[temp].cnt=-;
}
}
}
int main()
{
scanf("%d",&T);
while(T--)
{
root=;
head=tail=;
tot=;
res=;
memset(trie,,sizeof trie);
scanf("%d",&n);
for(int i=;i<n;i++)
{scanf("%s",word);
insert(root,word);
}
scanf("%s",artical);
build(root);
query(root,artical);
printf("%d\n",res);
}
return ;
}
HDU 2222 关键词查找的更多相关文章
- HDU 2222 AC自动机模板题
1.HDU 2222 2.题意:给出n个单词,一个字串,求有多少个单词在字串里出现了.注意给出的单词可能会重复,重复的不计. 3.总结:入门题.在查询这里还是不太懂. #include<bits ...
- HDU 2222 Keywords Search(AC自动机模版题)
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
- HDU 2222 Keywords Search(查询关键字)
HDU 2222 Keywords Search(查询关键字) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K ...
- VC模拟发送数据包-百度关键词查找
VC模拟发送数据包-百度关键词查找 逗比汪星人2009-09-06上传 VC模拟发送数据包-百度关键词abcdef查找 详情 http://blog.csdn.net/wangningyu htt ...
- HDU 2222 最简单的AC自动机套模板应用
HDU 2222 题意:给出N(N<=10,000)个单词,每个单词长度不超过50.再给出一个字符串S,字符串长度不超过1,000,000.问有多少个单词出现在了字符串S中.(单词可能重复,单词 ...
- HDU 2222 (AC自动机)
HDU 2222 Keywords search Problem : 给若干个模式串,询问目标串中出现了多少个模式串. Solution : 复习了一下AC自动机.需要注意AC自动机中的fail,和n ...
- HDU - 2222,HDU - 2896,HDU - 3065,ZOJ - 3430 AC自动机求文本串和模式串信息(模板题)
最近正在学AC自动机,按照惯例需要刷一套kuangbin的AC自动机专题巩固 在网上看过很多模板,感觉kuangbin大神的模板最为简洁,于是就选择了用kuangbin大神的模板. AC自动机其实就是 ...
- hdu 2222 Keywords Search ac自动机入门
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222 题意:有N(N <= 10000)个长度不超过50的模式串和一个长度不超过1e6的文本串. ...
- hdu 2222 Keywords Search
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222 思路:裸AC自动机,直接贴代码做模板 #include<stdio.h> #includ ...
随机推荐
- 2016-08-01一起领略ReactJs的风采
现在最热门的前端框架有AngularJS.React.Bootstrap等.自从接触了ReactJS,ReactJs的虚拟DOM(Virtual DOM)和组件化的开发深深的吸引了我,下面来跟我一起领 ...
- jquery点赞和取消点赞插件
<script> /* @author:Romey * 动态点赞 * 此效果包含css3,部分浏览器不兼容(如:IE10以下的版本) */ $(function(){ $("#p ...
- HDU5950(矩阵快速幂)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5950 题意:f(n) = f(n-1) + 2*f(n-2) + n^4,f(1) = a , f(2 ...
- css3 TransformZ() 3D缩放
transformZ()函数做了一个在Z轴移动的工作,3D空间中,Z轴垂直于x-y所在平面-也就是界面所在的平面,而我们的视角正好垂直于xy平面,所以进行transformZ() 3D缩放,其实在我们 ...
- PHP explode()函数
源起:将日期格式的字符串拆分成年.月.日,用于组织关系介绍信的特定位置打印.感谢倪同学提供思路 定义和用法 explode()函数把字符串分割为数组 语法 explode(separator,stri ...
- JSTL String时间转成 date
两个标签配合使用 <fmt:parseDate value="${integralRecord.startDate}" var="date1"/> ...
- cocos多点触控实效注意事项
一定要设置AppController.mm的 [eaglView setMultipleTouchEnabled:YES];
- 小夜灯V2.0成本
物料清单: Arduino Nano *1 17.98 HC-05主从机一体蓝牙模块 *1 15.9 RGB灯珠1W大功率带铝基板 *1 3.3 奶白灯罩 *1 32.5 锐澳9cm发光底座 *1 ...
- python 中md5 和 sha1 加密, md5 + os.urandom 生成全局唯一ID
首先先来介绍一下md5 和 sha1 的概念 MD5 MD5的全称是Message-Digest Algorithm 5(信息-摘要算法).128位长度.目前MD5是一种不可逆算法. 具有很高的安全性 ...
- linux curl 下载jdk
进入orecle官网,找到需要的安装包 需要cookie同意相关协议才能下载 curl -L "http://download.oracle.com/otn-pub/java/jdk/8u1 ...