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 ...
随机推荐
- UE4 代码编写细节:静态变量
Note:因为在切换关切时,会GC掉所有GameThread线程下的Object类,如果Static是UOBject 请调用AddToRoot函数 当然如果你的UObject子类Object是在自己 ...
- .Net Core + Angular2 环境搭建
环境搭建: 1)node.js版本>5.0,NPM版本>3.0,TypeScript版本>2.0(全装最新版就好了) 2)安装NTVS 1.2(node tools for vs), ...
- void 关键字
1. void 的字面意思为“无类型”,void*为“无类型指针”,void*可以指向任何类型的数据 2 用于数据类型封装,典型的如内存操作函数 memcpy 和 memset 的函数原型分别为: v ...
- DELL vostro V5460 装mSATA 半高SSD硬盘后装win8.1系统
1.介绍 DELL vostro V5460的超极本性能虽然不是那么好,但的确是我觉得样子最好看的一款.满足了,轻,薄.如果是红色的,则很适合女生用. 2.缺点 这款笔记本最大的缺点,就是有的无线网卡 ...
- G - 小希的迷宫
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status Pract ...
- android沉浸式状态栏设置(4.4以上版本)
其实设置比较简单,我用了小米和htc的几款机型都可以用. 主要代码就是这个(注意要在Activity的setContentView之前调用才行) /** * 开启沉浸式状态栏 * */ public ...
- Mac 配置Spark环境scala+python版本(Spark1.6.0)
1. 从官网下载Spark安装包,解压到自己的安装目录下(默认已经安装好JDK,JDK安装可自行查找): spark官网:http://spark.apache.org/downloads.html ...
- tcp之快速重传与恢复
本文为原创,转载请注明:http://www.cnblogs.com/gistao/ Background 写网络程序的都知道,tcp的窗口控制分为慢启动阶段和拥塞避免阶段,重传机制有快速重传/恢复和 ...
- 关于自定义Dialog的一次折腾
<新手,自己的简单理解,勿喷,有更好建议欢迎提出> 1.在设置dialog布局上的时候 我需要做一个圆角的dialog,我像往常一样定义一个<shape>然后做为我的dia ...
- bootstrap-14
基础导航条: 使用方法:1. 首先在制作导航的列表(<ul class="nav">)基础上添加类名"navbar-nav" 2.在列表外部添加一个 ...