• AC自动机简单第一题hdu 2222


    题目大意:

    给你一些单词,给你一篇文章,需要你求出其中文章中包含了多少个单词?

    例如其中的单词she、he、say、shr、her,文章yasherhs。

    那么首先根据单词建立出相应的字典树。

    和字典树不同的就是AC自动机要建立失败指针,实意就是为了让文章能够一次性的匹配下去。

    使得某些单词的后缀能够成为某些单词的前缀,使得模式串匹配的时候不至于浪费掉了之前所匹配的次数。

     匹配之后的指针走向:

                                   

    View Code
      1 #include<cstdio>
      2 #include<cstring>
      3 #define N 1000010
      4 char str[N];
      5 struct node
      6 {
      7        node *next[26];
      8        node *fail;
      9        int count;
     10        node()
     11        {
     12             count=0,fail=NULL;
     13             for(int i=0;i<26;i++)next[i]=NULL;
     14        }
     15 }*q[500010];
     16 int head,tail;
     17 void insert(node *root)
     18 {
     19      int i=0,index;
     20      node *p=root;
     21      while(str[i])
     22      {
     23          index=str[i]-'a';
     24          if(p->next[index]==NULL)p->next[index]=new node();
     25          p=p->next[index];
     26          i++;
     27      }
     28      p->count++;
     29 }
     30 void create_ac(node *root)
     31 {
     32      root->fail=NULL;
     33      q[head++]=root;
     34      while(head!=tail)
     35      {
     36            node *temp=q[tail++];
     37            node *p=NULL;
     38            for(int i=0;i<26;i++)
     39            {
     40                if(temp->next[i]!=NULL)
     41                {
     42                   if(temp==root)temp->next[i]->fail=root;
     43                   else
     44                   {
     45                      p=temp->fail;
     46                      while(p!=NULL)
     47                      {
     48                          if(p->next[i]!=NULL)
     49                          {
     50                             temp->next[i]->fail=p->next[i];
     51                             break;
     52                          }
     53                          p=p->fail;
     54                      }
     55                      if(p==NULL)temp->next[i]->fail=root;
     56                   }
     57                   q[head++]=temp->next[i];
     58                }
     59            }
     60       }
     61 }
     62 int query(node *root)
     63 {
     64     int answer=0,index,i=0;
     65     node *p=root;
     66     while(str[i])
     67     {
     68          index=str[i]-'a';
     69          while(p->next[index]==NULL&&p!=root)p=p->fail;
     70          p=p->next[index];
     71          p=(p==NULL)?root:p;
     72          node *temp=p;
     73          while(temp->count!=-1&&temp!=root)
     74          {
     75                answer+=temp->count;
     76                temp->count=-1;
     77                temp=temp->fail;
     78          }
     79          i++;
     80     }
     81     return answer;
     82 }
     83 int main()
     84 {
     85     int t,n;
     86     scanf("%d",&t);
     87     while(t--)
     88     {
     89           head=tail=0;
     90           scanf("%d",&n);
     91           node *root=new node();
     92           while(n--)
     93           {
     94                 scanf("%s",str);
     95                 insert(root);
     96           }
     97           create_ac(root);
     98           scanf("%s",str);
     99           printf("%d\n",query(root));
    100     }
    101     return 0;
    102 }
  • 相关阅读:
    HDU
    HDU
    西电OJ
    西电OJ
    西电OJ
    USACO 2.1-Healthy Holsteins
    USACO 2.1-Sorting a Three-Valued Sequence
    HDU
    UVA
    codeforces 811A Vladik and Courtesy
  • 原文地址:https://www.cnblogs.com/nuoyan2010/p/2938476.html
Copyright © 2020-2023  润新知