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) 所以我们今 ...
随机推荐
- CentOS5.6下安装Oracle10G软件 【保留报错经验】
CentOS5.6下安装Oracle10G ****************************************************************************** ...
- Swift - 炫酷放射弹出按钮菜单(改造自AwesomeMenu)
这个是一个第三方按钮菜单组件,原版是使用Objective-C编写的名为AwesomeMenu的组件,地址是:https://github.com/levey/AwesomeMenu 这里改造成了Sw ...
- 彻底搞定c指针
第一篇 变量的内存实质 一.先来理解C语言中变量的实质 要理解C指针,我认为一定要理解C中“变量”的存储实质,所以我就从“变量”这个东西开始讲起吧! 先来理解理解内存空间吧!请看下图: 内存地址→ ...
- Missile:双状态DP
题目 描写叙述 Long , long ago ,country A invented a missile system to destroy the missiles from their enem ...
- Lua获取网络时间
作者:ani_di 版权所有,转载务必保留此链接 http://blog.csdn.net/ani_di Lua获取网络时间 网络授时服务是一些网络上的时间服务器提供的时间,一般用于本地时钟同步. ...
- [Android学习笔记]Android Library Project的使用
RT http://developer.android.com/tools/projects/index.html
- 北京哪儿有卖tods豆豆鞋的?在线等答案、、、、(类似动物园、西单等地)_百度知道
北京哪儿有卖tods豆豆鞋的?在线等答案....(类似动物园.西单等地)_百度知道 北京哪儿有卖tods豆豆鞋的?在线等答案....(类似动物园.西单等地)
- IOS中的id与nil
1 id id和void *并非完全一样.在上面的代码中,id是指向struct objc_object的一个指针,这个意思基本上是说,id是一个指向任何一个继承了Object(或者NSObject) ...
- 用gradle管理android项目出现的问题以及解决方法
1.项目结构 最好是全部在root 项目配置 一个settings.gradle 一个build.gradle 2.多项目依赖 http://www.gradle.org/docs/current/u ...
- [Cocos2d-x]创建项目
从cocos2d-x 2.1.4之后,就不提供工程项目模板的安装文件了,我们只能手工修改以前的安装文件,让它连接最新的工程,但是这样很麻烦. 我们可以使用python命令创建cocos2d-x项目 步 ...