您的位置:首页 > 其它

ac自动机算法(Aho-Corasick 多模式匹配算法)

2016-12-26 00:00 369 查看
用于在输入的一串字符串中匹配有限组“字典”中的子串
它与普通字符串匹配的不同点在于同时与所有字典串进行匹配

AC自动机在匹配时如果当前字符匹配失败,那么利用fail指针进行跳转。由此可知如果跳转,跳转到的串的前缀,必为跳转前的模式串的后缀

失败指针的概念
假设有一个节点k,他的失败指针指向j。那么k,j满足这个性质:设root到j的距离为n, 则从k之上的第n个节点到k所组成的长度为n的单词,与从root到j所组成的单词相同。
建立失败指针数组
对于每个节点,我们可以这样处理:设这个节点上的字母为C,沿着他父亲的失败指针走,
直到走到一个节点,他的儿子中也有字母为C的节点。然后把当前节点的失败指针指向那个字目也为C的儿子。如果一直走到了root都没找到,
那就把失败指针指向root最开始,我们把root加入队列(root的失败指针显然指向自己),
这以后我们每处理一个点,就把它的所有儿子加入队列,直到搞完

char pattern[4][30]={"nihao","hao","hs","hsr"};

例如: niha节点的失败指针是节点 ha, 实际上失败指针是当前节点字符串的后缀字符串在tree树中对应的节点,实际上用的就是kmp算法的思想,对比的字符串的后缀直接使用,不再重新对比一遍了

失败指针的创建思路:

{"nihao","hao","hs","hsr", "hsn"}

假如是以上的几个字符串构成的tree树,



/**
1. n和h这2个二级节点的失败指针: root
2. ni这个三级节点的失败指针: 父节点的失败指针为root, root节点的子节点不存在i的节点, 所以ni的失败指针仍是root
3. ha这个三级节点的失败指针:父节点h的失败指针为root, 找root的子节点没有a,所以ha的失败指针也是root
4. hs这个三级节点的失败指针:父节点h的失败指针为root, 找root的子节点没有s,   所以hs的失败指针是root
5. nih这个四级节点的失败指针:父节点ni的失败指针为root, 找root的子节点有h,      所以nih的失败指针为h
6. hao这个四级节点的失败指针:  父节点ha的失败指针为root,找root的子节点没有o,     所以hao的失败指针为root
7. hsr这个四级节点的失败指针:父节点hs的失败指针为root,找root的子节点没有r,       所以hsr的失败指针为root
8. hsn这个四级节点的失败指针:父节点hs的失败指针为root,找root的子节点有n, 所以hsn的失败指针为n
9. niha这个五级节点的失败指针:父节点nih的失败指针为h,找h的子节点有a,  所以niha的失败指针为ha
10. nihao这个六级节点的失败指针:父节点niha的失败指针为ha, 找ha的子节点有o,所以nihao的失败指针为hao
tips: 如果一个节点的字符为m, 它的父节点的失败指针的子节点,没有找到m, 那么该怎么办呢,
如果它的父节点的失败指针为root,那么它的失败指针也指向root,
如果它的父节点的失败指针不是root,那么找 它的父节点的失败指针的父节点的失败指针,继续验证

以上所有节点处理完毕,每个节点的失败指针其实都是这个节点对应的最大存在后缀对应的节点

接收态:
这个状态的节点表示,这个从root到这个节点的字符串未匹配的字符串
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法