hdu 3065 AC自动机模版题

来源:互联网 发布:淘宝关键词挖掘大师 编辑:程序博客网 时间:2024/05/22 03:28

题意:输出每个模式串出现的次数,查询的时候呢使用一个数组进行记录就好。

同上题一样的关键点,其他没什么难度了。

#include <cstdio>#include <cstring>#include <queue>using namespace std;const int maxw = 1000 * 50 + 10;const int sigma_size = 128;const int maxl = 2000000 + 10;char str[1010][100];struct Trie{int next[maxw][sigma_size],fail[maxw],end[maxw];int root,L;int newnode(){for(int i=0;i<sigma_size;i++)    next[L][i]=-1;end[L++]=-1;return L-1;}void init(){L=0;root=newnode();}void insert(const char *s,int id){int now=root,len=strlen(s);for(int i=0;i<len;i++){if(next[now][s[i]]==-1)    next[now][s[i]]=newnode();now=next[now][s[i]];}end[now]=id;}void build(){queue<int>Q;fail[root]=root;for(int i=0;i<sigma_size;i++)    if(next[root][i]==-1)        next[root][i]=root;    else{    fail[next[root][i]]=root;    Q.push(next[root][i]);    }while(!Q.empty()){int now=Q.front();Q.pop();for(int i=0;i<sigma_size;i++)    if(next[now][i]==-1)        next[now][i]=next[fail[now]][i];    else{    fail[next[now][i]]=next[fail[now]][i];    Q.push(next[now][i]);    }}}int num[1000 + 10];void query(const char *buf,int n){memset(num,0,sizeof(num));int now=root,len=strlen(buf);for(int i=0;i<len;i++){now=next[now][buf[i]];int tmp=now;while(tmp!=root){if(end[tmp]!=-1)    num[end[tmp]]++;tmp=fail[tmp];}}for(int i=0;i<n;i++)  if(num[i])    printf("%s: %d\n",str[i],num[i]);}};char buf[maxl];Trie ac;int main(){int n;while(~scanf("%d",&n)){ac.init();for(int i=1;i<=n;i++){scanf("%s",str[i]);ac.insert(str[i],i);}ac.build();scanf("%s",buf);ac.query(buf,n);}return 0;}


 

原创粉丝点击