• 【hdu2222-Keywords Search】AC自动机基础裸题


    http://acm.hust.edu.cn/vjudge/problem/16403

    题意:给定n个单词,一个字符串,问字符串中出现了多少个单词。(若单词her,he,字符串aher中出现了两个单词)

    题解:

    每个单词末尾节点sum=1;
    find的时候每个点都顺着fail往上跳,加上该节点的sum,然后将这个sum清了;
    注意同一个单词出现多次只算一次。

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<queue>
      6 using namespace std;
      7 
      8 const int N=10100,L=1000100;
      9 char s[L];
     10 int num,n;
     11 struct node{
     12     int son[30];
     13     int fail,cnt;
     14 }a[N*60];
     15 queue<int> q;
     16 
     17 void clear(int x)
     18 {
     19     a[x].cnt=0;
     20     a[x].fail=0;
     21     memset(a[x].son,0,sizeof(a[x].son));
     22 }
     23 
     24 void trie(char *c)
     25 {
     26     int l=strlen(c);
     27     int x=0;
     28     for(int i=0;i<l;i++)
     29     {
     30         int t=c[i]-'a'+1;
     31         if(!a[x].son[t])
     32         {
     33             num++;
     34             clear(num);
     35             a[x].son[t]=num;
     36         }
     37         x=a[x].son[t];
     38     }
     39     a[x].cnt++;
     40 }
     41 
     42 void buildAC()
     43 {
     44     while(!q.empty()) q.pop();
     45     for(int i=1;i<=26;i++)
     46         if(a[0].son[i]) q.push(a[0].son[i]);
     47     while(!q.empty())
     48     {
     49         int x=q.front();q.pop();
     50         int fail=a[x].fail;
     51         for(int i=1;i<=26;i++) 
     52         {
     53             int y=a[x].son[i];
     54             if(y)
     55             {
     56                 a[y].fail=a[fail].son[i];
     57                 q.push(y);
     58             }
     59             else a[x].son[i]=a[fail].son[i];
     60         }
     61     }
     62 }
     63 
     64 int find(char *c)
     65 {
     66     int l=strlen(c);
     67     int x=0,ans=0;
     68     for(int i=0;i<l;i++)
     69     {
     70         int t=c[i]-'a'+1;
     71         while(x && !a[x].son[t]) x=a[x].fail;        
     72         x=a[x].son[t];
     73         int p=x;
     74         while(p && a[p].cnt!=-1)
     75         {
     76             ans+=a[p].cnt;
     77             a[p].cnt=-1;
     78             p=a[p].fail;
     79         }
     80     }
     81     return ans;
     82 }
     83 
     84 int main()
     85 {
     86     freopen("a.in","r",stdin);
     87     freopen("a.out","w",stdout);
     88     int T;
     89     scanf("%d",&T);
     90     while(T--)
     91     {
     92         scanf("%d",&n);
     93         num=0;
     94         clear(0);
     95         for(int i=1;i<=n;i++)
     96         {
     97             scanf("%s",s);
     98             trie(s);
     99         }
    100         buildAC();
    101         scanf("%s",s);
    102         printf("%d
    ",find(s));
    103     }
    104     return 0;
    105 }
  • 相关阅读:
    第五次作业
    第四次作业
    Java实验二
    java第一次作业
    第十一次作业
    第十次作业
    第九次作业
    第八次作业
    第七次作业
    第六次作业
  • 原文地址:https://www.cnblogs.com/KonjakJuruo/p/5686398.html
Copyright © 2020-2023  润新知