Keywords Search---hdu2222(AC自动机 模板)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222
一个常见的例子就是给出n个单词,再给出一段包含m个字符的文章,让你找出有多少个单词在文章里出现过;
本题就是最基础的模板;在此之前需要理解kmp和字典树(trie);
Trie树有3个基本性质:
(1) 根节点不包含字符,除根节点外每一个节点都只包含一个字符;
(2) 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串;
(3) 每个节点的所有子节点包含的字符都不相同。
1. AC自动机算法分为3步:
(1)构造一棵Trie树;
(2)构造失败指针;
构造失败指针的过程概括起来就一句话:设这个节点上的字母为x,沿着他父亲的失败指针走,
直到走到一个节点,他的儿子中也有字母为x的节点。然后把当前节点的失败指针指向那个字符
也为x的儿子。如果一直走到了root都没找到,那就把失败指针指向root。
1: root的子节点的失败指针都指向root。
2: 节点(字符为x)的失败指针指向:从X节点的父节点的fail节点回溯直到找到某节点的子节点也是字符x,没有找到就指向root。
(3)根据AC自动机,搜索待处理的文本。
从root节点开始,每次根据读入的字符沿着自动机向下移动。 当读入的字符,在分支中不存在时,递归走失败路径。
如果走失败路径走到了root节点, 则跳过该字符,处理下一个字符。 因为AC自动机是沿着输入文本的最长后缀移
动的,所以在读取完所有输入文本后,最后递归走失败路径,直到到达根节点, 这样可以检测出所有的模式。
搜索的步骤:
从根节点开始一次搜索;
取得要查找关键词的第一个字符,并根据该字符选择对应的子树并转到该子树继续进行检索;
在相应的子树上,取得要查找关键词的第二个字符,并进一步选择对应的子树进行检索。
迭代过程……
在某个节点处,关键词的所有字符已被取出,则读取附在该节点上的信息,即完成查找。
匹配模式串中出现的单词。当我们的模式串在Trie上进行匹配时,如果与当前节点的关键字不能继续匹配的时候,
就应该去当前节点的失败指针所指向的节点继续进行匹配。
匹配过程出现两种情况:
当前字符匹配,表示从当前节点沿着树边有一条路径可以到达目标字符, 此时只需沿该路径走向下一个节点继续匹配即可 ,目标字符串指针移向下个字符继续匹配;
当前字符不匹配,则去当前节点失败指针所指向的字符继续匹配,匹配过程随着指针指向root结束。
重复这2个过程中的任意一个,直到模式串走到结尾为止。
哎,看了大神的讲解:不会AC自动机基础的可以参考一下:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std; const int N = 1e6+;
char MumStr[N];
struct node
{
node *next[], *fail;
int leaf;///以该字符结束的个数
}; void AddTrie(char s[], node *head)///建立Trie树;
{
node *p = head;
for(int i=; s[i]; i++)
{
int k = s[i] - 'a'; if(p->next[k] == NULL)
p->next[k] = new node(); p = p->next[k];
}
p->leaf ++;///防止出现重复单词;
}
void GetFail(node *head)
{
queue<node*>Q;
Q.push(head);
while(Q.size())
{
node *p = Q.front();
Q.pop();
for(int i=; i<; i++)
{
if(p->next[i] != NULL)
{
node *t = p->fail;
///设这个节点上的字母为x,沿着他父亲的失败指针走,
///直到走到一个节点,他的儿子中也有字母为x的节点。
///然后把当前节点的失败指针指向那个字符也为x的儿子;
while(t != NULL) {
if(t->next[i] != NULL)
{
p->next[i]->fail = t->next[i];
break;
}
t = t->fail;
}
///如果一直走到了root都没找到,那就把失败指针指向root。
if(t == NULL)p->next[i]->fail = head;
Q.push(p->next[i]);
}
}
}
}
int Query(node *head)
{
int sum = ;
node *p = head;
for(int i=; MumStr[i]; i++)
{
int k = MumStr[i] - 'a'; while(p->next[k] == NULL && p != head)///当前字符不匹配;
p = p->fail;
if(p->next[k] == NULL)continue;
p = p->next[k];
node *t = p;
while(t!=head && t->leaf != -)
{
sum += t->leaf;
t->leaf = -;
t = t->fail;
}
}
return sum;
}
int main()
{
int T, n;
char s[];
scanf("%d", &T);
while(T--)
{
node *head = new node();
scanf("%d", &n);
for(int i=; i<n; i++)
{
scanf("%s", s);
AddTrie(s, head);
}
GetFail(head);
scanf("%s", MumStr);
int ans = Query(head);
printf("%d\n", ans);
}
return ;
}
Keywords Search---hdu2222(AC自动机 模板)的更多相关文章
- Keywords Search HDU2222 AC自动机模板题
ac自动机说起来很复杂,其实和kmp是一样的思路,都是寻找相同前后缀,减少跳的次数.只要理解了kmp是怎么求next数组的,ac自动机bfs甚至比knp还好写. 这里大致说一下kmp求next数组的方 ...
- HDU-2222 Keywords Search(AC自动机--模板题)
题目大意:统计一共出现了多少次模板串. 题目分析:AC自动机的模板题.不过这题有坑,相同的模板串不能只算一次. 代码如下: # include<iostream> # include< ...
- HDU2222 Keywords Search(AC自动机模板)
AC自动机是一种多模式匹配的算法.大概过程如下: 首先所有模式串构造一棵Trie树,Trie树上的每个非根结点都代表一个从根出发到该点路径的字符串. 然后每个结点都计算出其fail指针的值,这个fai ...
- HDU 2222 Keywords Search(AC自动机模板题)
http://acm.hdu.edu.cn/showproblem.php?pid=2222 题意:给出多个单词,最后再给出一个模式串,求在该模式串中包含了多少个单词. 思路: AC自动机的模板题. ...
- HDU 2222 Keywords Search 【AC自动机模板】
询问有多少个模式串出现在了文本串里面.将模式串插入Trie树中,然后跑一边AC自动机统计一下就哦了. 献上一份模板. #include <cstdio> #include <cstr ...
- HDU 2222:Keywords Search(AC自动机模板)
http://acm.hdu.edu.cn/showproblem.php?pid=2222 KMP是单模式串匹配的算法,而AC自动机是用于多模式串匹配的算法.主要由Trie和KMP的思想构成. 题意 ...
- hdu_2222: Keywords Search(AC自动机模板题)
题目链接 统计一段字符串中有多少个模板串在里面出现过 #include<bits/stdc++.h> using namespace std; ; struct Trie { ]; int ...
- [hdu2222] [AC自动机模板] Keywords Search [AC自动机]
AC自动机模板,注意!ch,Fail,lab数组的大小不是n而是节点个数,需要认真计算! #include <iostream> #include <algorithm> #i ...
- HDU2222 Keywords Search 【AC自动机】
HDU2222 Keywords Search Problem Description In the modern time, Search engine came into the life of ...
- HDU2222 Keywords Search(AC自动机)
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
随机推荐
- Handler实例
Handler使用例1这个例子是最简单的介绍handler使用的,是将handler绑定到它所建立的线程中.本次实验完成的功能是:单击Start按钮,程序会开始启动线程,并且线程程序完成后延时1s会继 ...
- sql server自定义函数
CREATE function [dbo].[f_testFunc]( ) ,) ) ) as begin ); ); ); ); SELECT @str_id = a.id,@str_code = ...
- ajax——用ajax写登陆页面
ajax.php <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://ww ...
- Redis-stat is not found
$ruby -v ruby 2.1.3p242 (2014-09-19 revision 47630) [x86_64-linux] $gem -v 2.2.2 $which ruby /usr/lo ...
- selenuim爬虫实战(日lofter.com)
LOFTER是网易公司2011年8月下旬推出的一款轻博客产品. LOFTER专注于为用户提供简约.易用.有品质.重原创的博客工具.原创社区,以及有品质的手机博客应用. LOFTER首次采用独立域名,口 ...
- arduino知识
如果你买过Adafruit, Sparkfun, Seeedstudio和Arduino Store的Kit,不难发现Arduino官方的无论从包装和印刷上都是最具艺术气质的,其次是Sparkfun, ...
- 分析HTML5中WebSocket的原理
目录结构 一.什么是Websocket websocket是html5提出的一个协议规范,参考rfc6455. 不过目前还都是在草案,没有成为标准,毕竟html5还在路上. websocket约定 ...
- java 基础数据结构
数据结构, 需要考虑两个方面: 1. 每个元素具体的存储方法 (java中是一个对象) 2. 元素之间的关系如何实现存储 (java中也是一个对象) 另外在java中, 已经可以把跟数据结构有关的一些 ...
- Hadoop周边生态软件和简要工作原理(二)
转自: http://www.it165.net/admin/html/201307/1532.html Sqoop: sqoop在hadoop生态系统中也是应用率比较高的软件,主要是用来做ETL工具 ...
- 【BZOJ】1011: [HNOI2008]遥远的行星(近似)
http://www.lydsy.com/JudgeOnline/problem.php?id=1011 题意:$f[i] = \sum_{j=1}^{i-1} \frac{M[i]M[j]}{i-j ...