Trie图
AC自动机是KMP的多串形式,当文本串失配时,AC自动机的fail指针告诉我们应该跳到哪里去继续匹配(跳到当前匹配串的最长后缀去),所以AC自动机的状态是有限的
但是AC自动机具有不确定性, 比如要求x结点的孩子c的fail指针(x->next[c]->fail), 如果x的fail指针指向的结点没有c孩子(x-fail->next[c]==NULL),
那么就要去看x的fail指针指向的结点的的fail指针指向的结点有没有孩子c(x->fail->fail->next[c] 是否为NULL),一直这样子迭代, 知道fail指针指向根结点为止
这样子的原因在于next指针的指向可能为空, Trie图就是补全了这些next指针的AC自动机,所以Trie图是确定性的有限状态自动机
那么如果补全这些next指针呢?
首先让第二层为空的next指针(第一层是根结点)都指向root,这是成里的, 如果匹配的时候如果第一个字符就不匹配, 那么肯定是回到root重新匹配
然后让下一层为空的next[i]指针指向上一层fail指针指向的next[i]指针(即也是指向自己的最长后缀)
Trie图的fail指针的求法与AC自动机一样, 这样子就能构件出Trie图了
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <math.h>
using namespace std;
#pragma warning(disable:4996)
typedef unsigned __int64 LL;
const int INF = <<;
/*
*/
const int N = ;
struct Node
{
int fail, next[];
bool isWord;
void init()
{
fail = -;
isWord = false;
for (int i = ; i < ; ++i)
next[i] = -;
}
}Trie[N];
int size;
void insert(int root, char *str)
{
int idx, cur = root;
for (int i = ; str[i]; ++i)
{
idx = str[i] - 'a';
if (Trie[cur].next[idx] == -)
{
Trie[size].init();
Trie[cur].next[idx] = size++;
}
cur = Trie[cur].next[idx];
}
Trie[cur].isWord = true;
}
void makeFail(int root)
{
queue<int> q;
for (int i = ; i < ; ++i)
{
if (Trie[root].next[i] == -)
Trie[root].next[i] = root;
else
{
Trie[Trie[root].next[i]].fail = root;
q.push(Trie[root].next[i]);
}
}
while (!q.empty())
{
int cur = q.front();
q.pop();
for (int i = ; i < ; ++i)
{
if (Trie[Trie[cur].fail].isWord)
Trie[cur].isWord = true;
if (Trie[cur].next[i] == -)
Trie[cur].next[i] = Trie[Trie[cur].fail].next[i];
else
{
Trie[Trie[cur].next[i]].fail = Trie[Trie[cur].fail].next[i];
q.push(Trie[cur].next[i]);
}
}
}
} int main()
{
int n, L;
char word[];
while (scanf("%d", &n,) != EOF)
{
Trie[].init();
Trie[].fail = ;
size = ;
for (int i = ; i < n; ++i)
{
scanf("%s", word);
insert(, word);
}
makeFail(); }
return ;
}
Trie图的更多相关文章
- 【BZOJ-2938】病毒 Trie图 + 拓扑排序
2938: [Poi2000]病毒 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 609 Solved: 318[Submit][Status][Di ...
- 【hihoCoder】1036 Trie图
题目:http://hihocoder.com/problemset/problem/1036 给一个词典dict,词典中包含了一些单词words.要求判断给定的一个文本串text中是否包含这个字典中 ...
- 【hihoCoder 1036】Trie图
看了一下简单的$Trie图$,调模板调啊调一连调了$2h$,最后发现$-'a'$打成$-'A'$了hhh,有种摔键盘的冲动. $Trie图$是$Trie树$上建立“前缀边”,不用再像在$Trie树$上 ...
- 字符串 --- KMP Eentend-Kmp 自动机 trie图 trie树 后缀树 后缀数组
涉及到字符串的问题,无外乎这样一些算法和数据结构:自动机 KMP算法 Extend-KMP 后缀树 后缀数组 trie树 trie图及其应用.当然这些都是比较高级的数据结构和算法,而这里面最常用和最熟 ...
- Trie图和Fail树
Trie图和AC自动机的区别 Trie图是AC自动机的确定化形式,即把每个结点不存在字符的next指针都补全了.这样做的好处是使得构造fail指针时不需要next指针为空而需要不断回溯. 比如构造ne ...
- hdu2457 Trie图+dp
hdu2457 给定n个模式串, 和一个文本串 问如果修改最少的字符串使得文本串不包含模式串, 输出最少的次数,如果不能修改成功,则输出-1 dp[i][j] 表示长度为i的字符串, 到达状态j(Tr ...
- CF 291E. Tree-String Problem [dfs kmp trie图优化]
CF291E 题意:一棵树,每条边上有一些字符,求目标串出现了多少次 直接求目标串的fail然后一边dfs一边跑kmp 然后就被特殊数据卡到\(O(n^2)\)了... 因为这样kmp复杂度分析的基础 ...
- AC自动机相关Fail树和Trie图相关基础知识
装载自55242字符串AC自动机专栏 fail树 定义 把所有fail指针逆向,这样就得到了一棵树 (因为每个节点的出度都为1,所以逆向后每个节点入度为1,所以得到的是一棵树) 还账- 有了这个东西, ...
- AC自动机学习笔记-2(Trie图&&last优化)
我是连月更都做不到的蒟蒻博主QwQ 考虑到我太菜了,考完noip就要退役了,所以我决定还是把博客的倒数第二篇博客给写了,也算是填了一个坑吧.(最后一篇?当然是悲怆のnoip退役记啦QAQ) 所以我们今 ...
随机推荐
- Android开发之搜Ya项目说明(3)
项目 搜芽移动client ----seller,app,base三个包的简单说明 作者 曾金龙 Tel:18664312687 QQ :470910357@qq.com 时间 2014-10-14 ...
- 应用程序初始化正常(0xc015002)失败解决方法
VS2005 sidebyside manifest error Microsoft.VC80.MFC Microsoft.VC80.CRT Microsoft.VC80.MFCLOC msvcr80 ...
- 在Window和Linux下使用Zthread库
ZThread库是一个开源的跨平台高级面向对象的线性和sycnchronization 库,以运行POSIX 和Win32 系统中的C++程序. ZThread库的主页:http://zthread. ...
- UVA 10313(完全背包变形)
Problem B Pay the Price Input: standard input Output: standard output Time Limit: 2 seconds Memory L ...
- wake_lock_timeout的用法
今天实用到用ec43_GPIO的中断来唤醒系统,将系统从深度休眠中唤醒并保证系统wakup 一段时间用过了.方法例如以下.有相同使用的童鞋能够參考一下. 1. 定义一人局部静态变量ec43_wlo ...
- python - ImportError: No module named http.cookies error when installing cherrypy 3.2 - Stack Overflow
python - ImportError: No module named http.cookies error when installing cherrypy 3.2 - Stack Overfl ...
- android 自己定义通知栏遇到的问题
首先看报错信息: E/AndroidRuntime(12220): FATAL EXCEPTION: main E/AndroidRuntime(12220): Process: gn.com.and ...
- Android自己定义组件系列【2】——Scroller类
在上一篇中介绍了View类的scrollTo和scrollBy两个方法,对这两个方法不太了解的朋友能够先看<自己定义View及ViewGroup> scrollTo和scrollBy尽管实 ...
- aMule代码分析(2)——CFileDataIO类和CFile类
aMule中的类很多,Maixee今天选择了两个比较基础的类,均是跟文件操作有关的,分别是CFileDataIO类和CFile类.其中,前者是基类,后者由它派生而出的.具体的继承关系,可以参考这张图: ...
- Android中怎样在应用A中启动或安装应用B
看到别人做的游戏攻略,想着自己的游戏攻略也加入新的功能,即Android中怎样在应用A中启动或安装应用B.就查了一些资料整理下来. 启动或安装对应的应用的方法: Step1:推断是否安装目标应用.仅仅 ...