AC自动机 模板 【HDU2222】 Keywords Search
2016-12-27 18:00
330 查看
AC自动机(Aho Corasick Automaton)
如果匹配字符串,一个模式串,一个匹配串,KMP就搞定了。
但是如果现在有多个模式串怎么办呢?每个模式串都处理一遍,再与匹配串匹配就太慢了,所以有了AC自动机,来解决这类问题。
AC自动机可以看成是Trie树和KMP的结合体,具体的实现方式就是在每个节点处增添一个fail指针,作用与KMP中的失配时用的跳转数组差不多(虽然在匹配的大多数时候都用不到它)。
但是fail指针最大的作用是AC自动机的建树,让一个状态的每个儿子都能进行状态转移(其实这里我已经偷换概念了QAQ,这个已经是Trie图,而不是AC自动机了)。
还有一个问题就是一个模式串可能包含另一个模式串,这时候可以通过跳fail指针来预处理该到该节点一共有多少单词。
(说的并不详细,但模板可用,如果想了解更多更深,还是去找其他神犇的博客)
【HDU2222 Keywords Serch】
题目大意:
给出n个串,然后给一篇文章,问这n个串有多少个在文章里面出现过
n个串中可能有完全相同的两个串,当做多个串
同一个串在文章中出现多次,不多次计算
题目分析:
AC自动机把所有串装里,然后把匹配串仍在里面跑一遍,途中搜集单词,最终输出答案。
注意事项:
1、注意走过的路要打标记,打了标记的地方有单词也不能加,会加重;
2、在写建树函数的时候l和r不能static(这个应该不会有别人和我犯一样的傻错误)。
代码如下:
如果匹配字符串,一个模式串,一个匹配串,KMP就搞定了。
但是如果现在有多个模式串怎么办呢?每个模式串都处理一遍,再与匹配串匹配就太慢了,所以有了AC自动机,来解决这类问题。
AC自动机可以看成是Trie树和KMP的结合体,具体的实现方式就是在每个节点处增添一个fail指针,作用与KMP中的失配时用的跳转数组差不多(虽然在匹配的大多数时候都用不到它)。
但是fail指针最大的作用是AC自动机的建树,让一个状态的每个儿子都能进行状态转移(其实这里我已经偷换概念了QAQ,这个已经是Trie图,而不是AC自动机了)。
还有一个问题就是一个模式串可能包含另一个模式串,这时候可以通过跳fail指针来预处理该到该节点一共有多少单词。
(说的并不详细,但模板可用,如果想了解更多更深,还是去找其他神犇的博客)
【HDU2222 Keywords Serch】
题目大意:
给出n个串,然后给一篇文章,问这n个串有多少个在文章里面出现过
n个串中可能有完全相同的两个串,当做多个串
同一个串在文章中出现多次,不多次计算
题目分析:
AC自动机把所有串装里,然后把匹配串仍在里面跑一遍,途中搜集单词,最终输出答案。
注意事项:
1、注意走过的路要打标记,打了标记的地方有单词也不能加,会加重;
2、在写建树函数的时候l和r不能static(这个应该不会有别人和我犯一样的傻错误)。
代码如下:
#include<cstdio> #include<algorithm> #include<string> #include<cstring> #include<cmath> #include<iostream> #include<cstdlib> #define N 1200000 using namespace std; int n,T; char c[60],s ; struct trie{ trie *son[26],*fail; int dc;bool lz; trie() { memset(son,0,sizeof(son)); dc=0;fail=NULL;lz=false; } void inser(char *s) { trie *c=this; for(int i=0;s[i];i++) { if(!c->son[s[i]-'a']) c->son[s[i]-'a']=new trie(); c=c->son[s[i]-'a']; } c->dc++; } }*V; void AC_automation() { static trie* dl ; int l=1,r=0; for(int i=0;i<26;i++) { if(!V->son[i]) V->son[i]=V; else {V->son[i]->fail=V;dl[++r]=V->son[i];} } trie *c,*t; while(l<=r) { c=dl[l++]; for(int i=0;i<26;i++) { if(!c->son[i]) c->son[i]=c->fail->son[i]; else {c->son[i]->fail=c->fail->son[i];dl[++r]=c->son[i];} } t=c->fail; while(t!=V && !t->dc) t=t->fail; c->fail=t; } } int query(char *s) { trie *c=V,*t;int ans=0; for(int i=0;s[i];i++) { c=c->son[s[i]-'a']; t=c; while(t!=V && !t->lz) {t->lz=true;ans+=t->dc;t=t->fail;} } return ans; } int main() { scanf("%d",&T); while(T--) { scanf("%d",&n); V=new trie(); for(int i=1;i<=n;i++) { scanf("%s",c); V->inser(c); } AC_automation(); scanf("%s",s); int ans=query(s); printf("%d\n",ans); } return 0; }
相关文章推荐
- [AC自动机(模板题)] hdu2222 Keywords Search
- 【HDU2222】【AC自动机模板 测烂为止】Keywords Search
- Keywords Search---hdu2222(AC自动机 模板)
- ac自动机模板(hdu2222)
- HDU-2222 Keywords Search (AC自动机模板)
- 【AC自动机】[HDU2222]Keywords Search
- ac自动机模板hdu2222
- hdu2222 ac自动机模板
- HDU 2222 Keywords Search(我的第一道AC自动机,模板题)
- hdu2222 ac自动机模板
- HDU2222 Keywords Search [AC自动机模板]
- hdu2222 AC自动机入门 指针型模板
- hdu2222-Keywords Search 【AC自动机】
- HDU2222 Keywords Search [AC自动机模板]
- AC自动机 HDU2222 Keywords Search
- AC自动机模板(hdu2222)
- hdu2222-AC自动机&模板-Keywords Search
- AC自动机 HDU2222 Keywords Search
- 【字符串·AC自动机】hdu2222 Keywords Search
- HDU2222 Keywords Search 【AC自动机模板题】