从0开始 数据结构 AC自动机 hdu 2222
失配指针原理
使当前字符失配时跳转到另一段从root开始每一个字符都与当前已匹配字符段某一个后缀完全相同且长度最大的位置继续匹配,如同KMP算法一样,AC自动机在匹配时如果当前字符串匹配失败,那么利用失配指针进行跳转。由此可知如果跳转,跳转后的串的前缀必为跳转前的模式串的后缀,并且跳转的新位置的深度(匹配字符个数)一定小于跳之前的节点(跳转后匹配字符数不可能大于跳转前,否则无法保证跳转后的序列的前缀与跳转前的序列的后缀匹配)。所以可以利用BFS在Trie上进行失败指针求解。
简单来说
失败指针的作用就是将主串某一位之前的所有可以与模式串匹配的单词快速在Trie树中找出。
构建失败指针
构造失败指针的过程概括起来就一句话:设这个节点上的字母为C,沿着它父亲节点的失败指针走,直到走到一个节点,它的子结点中也有字母为C的节点。然后把当前节点的失败指针指向那个字母也为C的儿子。如果一直走到了root都没找到,那就把失败指针指向root。
具体操作起来
先把root加入队列(root的失败指针指向自己或者NULL),这以后我们每处理一个点,就把它的所有儿子加入队列。
匹配
匹配过程分两种情况:
(1)当前字符匹配,表示从当前节点沿着树边有一条路径可以到达目标字符,此时只需沿该路径走向下一个节点继续匹配即可,目标字符串指针移向下个字符继续匹配;
(2)当前字符不匹配,则去当前节点失败指针所指向的字符继续匹配,匹配过程随着指针指向root结束。重复这2个过程中的任意一个,直到模式串走到结尾为止。
hdu2222 Keywords Search
Problem Description
In the modern time, Search engine came into the life of everybody like Google, Baidu, etc.
Wiskey also wants to bring this feature to his image retrieval system.
Every image have a long description, when users type some keywords to find the image, the system will match the keywords with description of image and show the image which the most keywords be matched.
To simplify the problem, giving you a description of image, and some keywords, you should tell me how many keywords will be match.
Input
First line will contain one integer means how many cases will follow by.
Each case will contain two integers N means the number of keywords and N keywords follow. (N <= 10000)
Each keyword will only contains characters 'a'-'z', and the length will be not longer than 50.
The last line is the description, and the length will be not longer than 1000000.
Output
Print how many keywords are contained in the description.
Sample Input
1
5
she
he
say
shr
her
yasherhs
Sample Output
3
代码如下:
//http://blog.csdn.net/creatorx/article/details/71100840
#include <iostream>
#include <cstdio>
#include <cstring>
//ac 自动机
using namespace std;
const int maxn = 26;
char s[100005];
char keyword[55];
struct node
{
node * next[maxn];
node * fail;
int sum;//相应的个数
node()
{
for(int i = 0 ; i < maxn; i++)
next[i] = NULL;
fail = NULL;
sum = 0;
}
};
node * q[500005];
node * root;
void Build_Trie(char * s)
{
node * p = root;
int len = strlen(s);
for(int i = 0 ; i < len ; i++)
{
int tmp = s[i]-'a';
if(p->next[tmp] == NULL)
{
node *newnode = new node;
p->next[tmp] = newnode;
}
p = p->next[tmp];
}
p->sum++;
}
void build_fail_pointer()
{
int head = 0;
int tail = 0;
q[head++] = root;
node * p, *tmp;
while(head != tail)
{
tmp = q[tail++];
for(int i = 0 ; i < maxn; i++)
{
if(tmp->next[i] != NULL)
{
//所有第一层的点都要指向root
if(tmp == root)
{
tmp->next[i]->fail = root;
}
else
{
p = tmp->fail;
while(p != NULL)
{
if(p->next[i] != NULL)
{
tmp->next[i]->fail = p->next[i];
break;
}
p = p->fail;
}
if(p == NULL)
tmp->next[i]->fail = root;
}
q[head++] = tmp->next[i];
}
}
}
}
int query(node * root)
{
int i, v, cnt = 0;
node *p = root;
int len = strlen(s);
for(int i = 0 ; i < len; i++)
{
v = s[i]-'a';
while(p->next[v] == NULL && p!=root)
p = p->fail;
p = p->next[v];
if(p == NULL)
p = root;
node * tmp = p;
while(tmp != root)
{
if(tmp->sum >= 0)
{
cnt += tmp->sum;
tmp->sum = -1;
}
else
break;
tmp = tmp->fail;
}
}
return cnt;
}
int main()
{
int T, n;
scanf("%d",&T);
while(T--)
{
root = new node;
scanf("%d",&n);
for(int i = 0 ; i < n ; i++)
{
scanf("%s",keyword);
Build_Trie(keyword);
}
build_fail_pointer();
scanf("%s",s);
printf("%d\n",query(root));
}
return 0;
}
从0开始 数据结构 AC自动机 hdu 2222的更多相关文章
- 数据结构--AC自动机--hdu 2896
病毒侵袭 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
- 从0开始 数据结构 AC自动机 模板(from kkke)
AC自动机模板 2.4.1 头文件&宏&全局变量 #include <queue> #define MAXN 666666 #define MAXK 26//字符数量 st ...
- AC自动机 HDU 2222
t n个字串 1个母串 求出现几个字串 字串可能重复 #include<stdio.h> #include<algorithm> #include<string.h> ...
- 【暑假】[实用数据结构] AC自动机
Aho-Corasick自动机 算法: <功能> AC自动机用于解决文本一个而模板有多个的问题. AC自动机可以成功将多模板匹配,匹配意味着算法可以找到每一个模板在文本中出现的位置. & ...
- AC自动机 HDU 3065
大概就是裸的AC自动机了 #include<stdio.h> #include<algorithm> #include<string.h> #include< ...
- AC自动机 HDU 2896
n个字串 m个母串 字串在母串中出现几次 #include<stdio.h> #include<algorithm> #include<string.h> #inc ...
- AC自动机 HDOJ 2222 Keywords Search
题目链接 题意:每个文本串的出现次数 分析:入门题,注意重复的关键字算不同的关键字,还有之前加过的清零. 新模板,加上last跑快一倍 #include <bits/stdc++.h> ...
- AC 自动机——多模式串匹配
网站上的敏感词过滤是怎么实现的呢? 实际上,这些功能最基本的原理就是字符串匹配算法,也就是通过维护一个敏感词的字典,当用户输入一段文字内容后,通过字符串匹配算法来检查用户输入的内容是否包含敏感词. B ...
- (转)两种高效过滤敏感词算法--DFA算法和AC自动机算法
原文:https://blog.csdn.net/u013421629/article/details/83178970 一道bat面试题:快速替换10亿条标题中的5万个敏感词,有哪些解决思路? 有十 ...
随机推荐
- Laravel 5.x HTTPS反向代理的实现
需求 可针对多个域名设置HTTPS并指向到同一个项目. 最先考虑到的是通过nginx的反向代理来实现,最终测试发现效果并不完美. 示例如下: server { listen 127.0.0.1:808 ...
- android开发笔记(二)导入项目到eclipse和另一个项目
NND,eclipse里导入工程出现问题了,整了半天,来个这问题,无效工程描述,找了半天看.projec文件是否工程名对应,看androidManifest.XML换里面的代码版本号,我擦都无济于事. ...
- Period II---fzu1901(Next数组)
题目链接:http://acm.fzu.edu.cn/problem.php?pid=1901 给你一个字符串 s 求出所有满足s[i] == s[i+p] ( 0 < i+p < len ...
- 兼容获取scrollTop和scrollLeft(被滚动条卷走的部分)
function scroll() { //ie9+ 标准浏览器 if (window.pageYOffset != null) { return { left: window.pageXOffset ...
- django 模板语言之 filter 自定义模板
可以自己写python函数放在模板语言里用 这种方法是django里面的 filter {{ item.event_start|date:"Y-m-d H:i:s"}} {{ bi ...
- PAT 1049 Counting Ones [难]
1049 Counting Ones (30 分) The task is simple: given any positive integer N, you are supposed to coun ...
- Python:6种标准数据类型
原文地址https://www.cnblogs.com/qin1991/p/5910145.html #!/usr/bin/python3 #python的基本语法和数据类型 #python3中 一行 ...
- Mvc ModelState.isValid为false时,检查时那个字段不符合规则的代码
List<string> sb = new List<string>(); //获取所有错误的Key List<string> Keys = ModelState. ...
- ruby 时间 今天 昨天
today = Time.now.strftime('%Y-%m-%d') yesterday = (Time.now - 1.day).strftime('%Y-%m-%d')
- Mybatis入门配置
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis .20 ...