HDU 2222 Keywords Search题解与翻译

来源:互联网 发布:卡尔曼滤波算法推导 编辑:程序博客网 时间:2024/05/24 00:04

【题目大意】给出多组数据(第一行输入的N),每组数据第一行给出要录入的单词数,最后一行给出文章,要求计算录入的单词在文章中出现了多少次。

【分析】很裸的AC自动机。首先建一棵Trie树,再用类似于KMP的next数组一样对每一个Trie树结点求出对应的失败指针,从而在每次失败后,在每个录入单词中找一个最优的串的合适的位置继续进行匹配,最后对文章进行匹配即可。

→为方便查阅,给出链接:

      Trie树百度百科:http://baike.baidu.com/view/1436495.htm

      KMP详解:http://blog.csdn.net/u011400953/article/details/9324095

【原题地址】http://acm.hdu.edu.cn/showproblem.php?pid=2222

【代码】

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<iostream>#include<algorithm>#include<queue>using namespace std;#define MAX 500001struct TREE{int fail,son[26+6],num;};TREE trie[MAX];int CASE,N,node_num=0;int ans=0;char NOW1[101],NOW2[1000001];void tree_clear(){ans=0;node_num=0;for(int i=0;i<=N;i++){  trie[i].fail=0;  trie[i].num=0;  for(int j=0;j<=26;j++)        trie[i].son[j]=0;}}void insect(char *NOW){int now=0,len=strlen(NOW);for(int i=0;i<len;i++){  if(!trie[now].son[(int)NOW[i]-(int)'a'])        trie[now].son[(int)NOW[i]-(int)'a']=++node_num;  now=trie[now].son[(int)NOW[i]-(int)'a'];}trie[now].num++;//=1 ?}void build_fail(){queue<int> q;int now=0;for(int i=0;i<26;i++)      if(trie[now].son[i])      {            q.push(trie[now].son[i]);            trie[trie[now].son[i]].fail=0;      }while(!q.empty()){  int point,now_fail;  now=q.front();  q.pop();  for(int i=0;i<26;i++)        if(point=trie[now].son[i])        {            now_fail=trie[now].fail;            while(now_fail && !trie[now_fail].son[i])               now_fail=trie[now_fail].fail;      trie[point].fail=trie[now_fail].son[i];      q.push(point);        }}}void find(char *NOW){int len=strlen(NOW),now=0,use=0;for(int i=0;i<len;i++){  while(now && !trie[now].son[(int)NOW[i]-(int)'a'])        now=trie[now].fail;  now=trie[now].son[(int)NOW[i]-(int)'a'];  use=now;  while(use)  {     ans+=trie[use].num;     trie[use].num=0;     use=trie[use].fail;  }}}int main(){//freopen("test.in","r",stdin);//freopen("test.out","w",stdout);scanf("%d",&CASE);for(int i=1;i<=CASE;i++){      scanf("%d",&N);  tree_clear();  for(int j=1;j<=N;j++)  {      scanf("%s",NOW1);      insect(NOW1);  }  build_fail();  scanf("%s",NOW2);  find(NOW2);  printf("%d\n",ans);}return 0;}


 转载注明出处:http://blog.csdn.net/u011400953

原创粉丝点击