从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万个敏感词,有哪些解决思路? 有十 ...
随机推荐
- [genome shell]标题栏优化
参考地址:https://wiki.archlinux.org/index.php/GNOME_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)#.E4.BB.8E.E5. ...
- Spark源码分析 – SparkContext
Spark源码分析之-scheduler模块 这位写的非常好, 让我对Spark的源码分析, 变的轻松了许多 这里自己再梳理一遍 先看一个简单的spark操作, val sc = new SparkC ...
- zipline自制data bundles
Databundle zipline 缺省提供了一些行情的data bundle , 可以通过 zipline bundles 查看 其中 quandl 数据源是从 https://www.quand ...
- Python:解析properties文件
在项目中遇到解析properties的情况,而Python中正好没有解析properties文件的现成模块,于是从网上找到了这个脚本,有一些小地方修改了一下 原博客: Python读写properti ...
- Java compiler level does not match解决方法, java 修改编译用的jdk的方法
从别的地方导入一个项目的时候,经常会遇到eclipse/Myeclipse报Description Resource Path Location Type Java compiler level d ...
- send/receive h264/aac file/data by rtp/rtsp over udp/tcp
一.安装一些必要的调试工具 1.vlc安装sudo apt-get install vlcsudo apt-get install vlc-nox 2.ffmpeg安装,带ffplay,ffplay依 ...
- python学习笔记(八)python操作Excel
一.python操作excel,python操作excel使用xlrd.xlwt和xlutils模块,xlrd模块是读取excel的,xlwt模块是写excel的,xlutils是用来修改excel的 ...
- MySQL8.0新特性
一.修改密码修改root密码之前要先flush privileges;ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'f ...
- 素数判断 - C语言实现
除了1和自身之外不能整除其它数, 称之为素数. 最小的素数是2. 没有最大的素数. 1000以内素数, 如下图所示: 关于素数的算法, 一般有2种. 第1种, 给出一个数n(n >= 2), 判 ...
- yii2美化url
http://blog.csdn.net/xundh/article/details/45418265