参考博客

失配指针原理

使当前字符失配时跳转到另一段从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的更多相关文章

  1. 数据结构--AC自动机--hdu 2896

    病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  2. 从0开始 数据结构 AC自动机 模板(from kkke)

    AC自动机模板 2.4.1 头文件&宏&全局变量 #include <queue> #define MAXN 666666 #define MAXK 26//字符数量 st ...

  3. AC自动机 HDU 2222

    t n个字串 1个母串 求出现几个字串 字串可能重复 #include<stdio.h> #include<algorithm> #include<string.h> ...

  4. 【暑假】[实用数据结构] AC自动机

    Aho-Corasick自动机  算法: <功能> AC自动机用于解决文本一个而模板有多个的问题. AC自动机可以成功将多模板匹配,匹配意味着算法可以找到每一个模板在文本中出现的位置. & ...

  5. AC自动机 HDU 3065

    大概就是裸的AC自动机了 #include<stdio.h> #include<algorithm> #include<string.h> #include< ...

  6. AC自动机 HDU 2896

    n个字串 m个母串 字串在母串中出现几次 #include<stdio.h> #include<algorithm> #include<string.h> #inc ...

  7. AC自动机 HDOJ 2222 Keywords Search

    题目链接 题意:每个文本串的出现次数 分析:入门题,注意重复的关键字算不同的关键字,还有之前加过的清零.   新模板,加上last跑快一倍 #include <bits/stdc++.h> ...

  8. AC 自动机——多模式串匹配

    网站上的敏感词过滤是怎么实现的呢? 实际上,这些功能最基本的原理就是字符串匹配算法,也就是通过维护一个敏感词的字典,当用户输入一段文字内容后,通过字符串匹配算法来检查用户输入的内容是否包含敏感词. B ...

  9. (转)两种高效过滤敏感词算法--DFA算法和AC自动机算法

    原文:https://blog.csdn.net/u013421629/article/details/83178970 一道bat面试题:快速替换10亿条标题中的5万个敏感词,有哪些解决思路? 有十 ...

随机推荐

  1. Xcode自带工具symbolicatecrash解析Crash文件

    项目中遇到一台手机运行测试包闪退的现象,而且是一个设备闪退其他设备没有再现的情况 可以看到Crash信息,但是指定的问题给出的是16进制内存地址,根本无法定位问题发生在哪个类的哪个函数中 所以需要解析 ...

  2. MySQL exists 和 not exists 的用法

    有一个查询如下: 1 SELECT c.CustomerId, c.CompanyName   2 FROM Customers c   3 WHERE EXISTS(   4     SELECT  ...

  3. F5刷新与在地址栏按回车的区别

    “F5刷新”,它是在你现有页面的基础上,检查网页是否有更新的内容.在检查时,会保留之前的一些变量的值: “转到”和在地址栏回车,则相当于你重新输入网页的URL访问,这种情况下,浏览器会尽量使用已经存在 ...

  4. Zipline Beginner Tutorial

    Zipline Beginner Tutorial Basics Zipline is an open-source algorithmic trading simulator written in ...

  5. 剑指Offer——和为S的两个数字

    题目描述: 输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的.   输入描述: 对应每个测试案例,输出两个数,小的先输出. ...

  6. JS获取当前网页大小以及屏幕分辨率等

    网页可见区域宽:document.body.clientWidth 网页可见区域高:document.body.clientHeight 网页可见区域宽:document.body.offsetWid ...

  7. Spark Standalone Mode 单机启动Spark -- 分布式计算系统spark学习(一)

    spark是个啥? Spark是一个通用的并行计算框架,由UCBerkeley的AMP实验室开发. Spark和Hadoop有什么不同呢? Spark是基于map reduce算法实现的分布式计算,拥 ...

  8. 源码包安装(Python mysql redis)

    一  源码包安装 (1)python3.6源码包安装 ./configure ------> 定制功能 make make install mysql 源码包 cmake make make i ...

  9. git学习------>Git 分支管理最佳实践

    ps:本文转载于 : https://www.ibm.com/developerworks/cn/java/j-lo-git-mange/index.html Git 是目前最流行的源代码管理工具.大 ...

  10. JavaScript工具库 lodash 中文文档 英文文档

    https://lodash.com/docs/    英文版 http://lodashjs.com/docs/   中文版 http://www.css88.com/doc/lodash/ 中文版 ...