2011年04月06日
来源:互联网 发布:视频人脸打马赛克软件 编辑:程序博客网 时间:2024/05/17 00:55
题目 :http://acm.hdu.edu.cn/showproblem.php?pid=2222
题目大意 :给出字典和文本,看字典中的单词在文本中出现了几个。
考查点 :AC自动机
思路 :既然是多串匹配问题,肯定是要用到AC自动机会比较好,但是看了网上很多的AC自动机的解题报告都不是很完整的AC自动机,他们只是建立出来了失败指针,也就是说他们的只是简单的trie+KMP,而没有真正的建立出DFA来,一个DFA应该能够提供有限的字符集组成的串无止尽的在上边运转,应此ac自动机也应该是一个所有节点的字符边都指出去的有向图,而且这个图必然是有环的。而且这个图是饱满的,就拿由小写字母字符集|∑|组成的自动机,那么每个节点的26个指针都应是指出去的,如果这个节点本身就具有某些字符边,那正好,如果没有,就需要我们把虚边加进去,加虚边的时候就会用到后缀指针,也可说是失败指针,因为当我们走到某一位置与当前模式串匹配失败的时候,我们希望的就是能够找到失配位之前的其它模式串与这个模式串具有最长的后缀,那么如果我们是因为字符C匹配失败,我们就可以直接沿着他失败指针的c孩子继续往下走,如果他的失败指针没有c孩子怎么办?别急,在找他的失败指针时,他的失败指针的26的指针我们已经全部建立起来,一次即使他的失败指针没有真正的c孩子,也会有虚边已经建立起来,因此最多就是虚边加回了根点。因为我们规定了根节点出发的虚边都指向自己,且根节点的失败指针是自己,根节点的所有孩子的失败指针是根节点,其它节点(假设是由c指向的节点)的失败指针就按他的最长后缀找,也就是他父节点的失败指针指向节点的c孩子,他的虚边自然就是他失败指针的对应的孩子。
下面给出详细的建图的过程,前提是建立好了trie树
[键入文档的引述或关注点的摘要。您可将文本框放置在文档中的任何位置。请使用“绘图工具”选项卡更改引言文本框的格式。]
l
l
l
l
l
l
l
l
l
l
详细讲解见王赟的论文《trie图的构建、活用与改进》
如果说一般的AC自动机是KMP+trie 的思想,那么我觉得这个AC自动机就是对其的一个改进,在我们充分的利用的我们已经申请的空间的同时,节约了查找时间(匹配时不需要跳跃),这样的操作太完美了。
其中要注意的是如果一个模式串是另一个模式串的子串就会出问题,这个是需要解决的问题,也很好解决就是因为那个模式串是这个模式串的子串,设串为bacd和ac 那么bacd的ac指针肯定直接或间接的指向ac,这样我们就可以通过向上递推的看他的失败指针的是否为一个模式串来找到所有的串。这也是ac自动机的神奇之处啊。 据说自动机可以描绘整个世界,向往啊
提交情况 ,
心得体会若干,全在上面了。
AC code
#include <stdio.h>
#include <string.h>
struct NODE{
} trie[255555];
int ad;
char T[1000010];
intqueue[255555], boo[255555];
voidinsert(){
}
voidGet_trie_map(){
}
voidBuilt_trie(intM){
}
int Find(){
}
int main(){
}
- 2011年04月06日
- 2011年04月06日的日记
- 2011年06月23日晚上
- 2011年06月22日晚上
- 2011年06月21日晚上
- 2011年06月21日上午
- 2011年06月21日
- 2011年06月21日
- 2011年06月24日
- 2011年06月24日
- 2011年06月24日
- 2011年06月24日
- 2011年06月24日
- 2011年06月24日
- 2011年06月20日
- 2011年06月10日
- 2014年06月04日
- 2014年06月04日
- 2011年03月21日的日记
- activemq-jms --zhuanzai
- poj2406 KMP算法
- poj1961 KMP
- AC自动机(确定性有限状态自动机)
- 2011年04月06日
- HTML5之Web Worker
- 2011年04月06日的日记
- 模拟退火 poj3422 run away
- hdu3689 AC自动机Dp
- 平面最近圆对儿 hdu3124
- hdu3400 三分法
- 智能避障小车顺利结束
- 内部类和外部类