• AC自动机【模板】+经典例题


    AC自动机模板

    经典例题

    Keywords Search HDU - 2222

    【求目标串中出现了几个模式串】

    【(注意:模式串可能会重复)】

    模板:

     1 const int maxn=26;
     2 struct Trie
     3 {
     4     int next[500010][maxn];
     5     int fail[500010],end[500010];
     6     int root,L;
     7     int newnode() //初始化 
     8     {
     9         for(int i=0;i<26;i++)
    10         next[L][i]=-1;
    11         end[L++]=0;
    12         return L-1;
    13     }
    14 
    15     void init()//初始化 
    16     {
    17         L=0;
    18         root=newnode();
    19     }
    20     void insert(char s[])//构造树trie 
    21     {
    22         int len=strlen(s);
    23         int now=root;
    24         for(int i=0;i<len;i++)
    25         {
    26             if(next[now][s[i]-'a']==-1)
    27               next[now][s[i]-'a']=newnode();
    28             now=next[now][s[i]-'a'];  
    29         }
    30         end[now]++;
    31     }
    32 
    33     void build()//构造失败指针 
    34     {
    35         queue<int>Q;
    36         fail[root]=root;
    37         for(int i=0;i<26;i++)
    38         if(next[root][i]==-1)
    39             next[root][i]=root;
    40         else
    41         {
    42             fail[next[root][i]]=root;
    43             Q.push(next[root][i]);
    44         }
    45         while(!Q.empty())
    46         {
    47             int now=Q.front();
    48             Q.pop();
    49             for(int i=0;i<26;i++)
    50                 if(next[now][i]==-1)
    51                     next[now][i]=next[fail[now]][i];
    52                     else
    53                     {
    54                         fail[next[now][i]]=next[fail[now]][i];
    55                         Q.push(next[now][i]);
    56                     }
    57 
    58                 }       
    59     }
    60 
    61   void query(char buf[])//查询 
    62   {
    63     int len=strlen(buf);
    64     int now=root;
    65     int sum=0;
    66     for(int i=0;i<len;i++)
    67     {
    68             now = next[now][buf[i]-'a'];
    69             int temp = now;
    70             while(temp != root)
    71             {
    72 
    73                 sum+=end[temp];
    74                 end[temp]=0;//避免重复计算 
    75                 temp = fail[temp];
    76             }
    77       }
    78         printf("%d
    ",sum);
    79     }
    80   };

    病毒侵袭 HDU - 2896  

    【统计目标串中模式串的个数】

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<queue>
      6 #include<vector>
      7 #include<cmath>
      8 #include<string>
      9 #include<map>
     10 #define LL long long  
     11 using namespace std;
     12 const int maxn=128;//模板部分
     13 struct Trie
     14 {
     15     int next[210*500][maxn];
     16     int fail[210*500],end[210*500];
     17     int root,L;
     18     int newnode() //初始化 
     19     {
     20         for(int i=0;i<128;i++)
     21         next[L][i]=-1;
     22         end[L++]=-1;
     23         return L-1;
     24     }
     25 
     26     void init()//初始化 
     27     {
     28         L=0;
     29         root=newnode();
     30     }
     31     void insert(char s[],int id)//构造树trie 
     32     {
     33         int len=strlen(s);
     34         int now=root;
     35         for(int i=0;i<len;i++)
     36         {
     37             if(next[now][s[i]]==-1)
     38               next[now][s[i]]=newnode();
     39             now=next[now][s[i]];  
     40         }
     41         end[now]=id;//记录单词的id
     42     }
     43 
     44     void build()//构造失败指针 
     45     {
     46         queue<int>Q;
     47         fail[root]=root;
     48         for(int i=0;i<128;i++)
     49         if(next[root][i]==-1)
     50             next[root][i]=root;
     51         else
     52         {
     53             fail[next[root][i]]=root;
     54             Q.push(next[root][i]);
     55         }
     56         while(!Q.empty())
     57         {
     58             int now=Q.front();
     59             Q.pop();
     60             for(int i=0;i<128;i++)
     61                 if(next[now][i]==-1)
     62                     next[now][i]=next[fail[now]][i];
     63                     else
     64                     {
     65                         fail[next[now][i]]=next[fail[now]][i];
     66                         Q.push(next[now][i]);
     67                     }
     68 
     69                 }       
     70     }
     71 
     72 
     73   bool vis[510];
     74   bool query(char buf[],int n,int id)//查询 
     75   {
     76     int len=strlen(buf);
     77     int now=root;
     78     memset(vis,0,sizeof(vis));
     79     bool flag=false;
     80     for(int i=0;i<len;i++)
     81     {
     82             now = next[now][buf[i]];
     83             int temp = now;
     84             while(temp != root)
     85             {
     86                 if(end[temp] != -1)
     87                 {
     88                     vis[end[temp]] = true;
     89                     flag = true;
     90                 }
     91                 temp = fail[temp];
     92             }
     93       }
     94       if(!flag)return false;
     95         printf("web %d:",id);
     96         for(int i = 1;i <= n;i++)
     97             if(vis[i])
     98                 printf(" %d",i);
     99         printf("
    ");
    100         return true;
    101     }
    102   };
    103 char str1[205]; 
    104 char str2[10010];
    105 Trie ac;
    106 int main()
    107 {
    108     int n,m;
    109     while(scanf("%d",&n) != EOF)
    110     {
    111         ac.init();
    112         for(int i = 1;i <= n;i++)
    113         {
    114             scanf("%s",str1);
    115             ac.insert(str1,i);
    116         }
    117         ac.build();
    118         int ans = 0;
    119         scanf("%d",&m);
    120         for(int i = 1;i <= m;i++)
    121         {
    122             scanf("%s",str2);
    123             if(ac.query(str2,n,i))
    124                 ans++;
    125         }
    126         printf("total: %d
    ",ans);
    127     }
    128     return 0;
    129 }

    病毒侵袭持续中 HDU - 3065

    【思路:和病毒侵袭 HDU - 2896 这题差不多,只是多了一个计数。】

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<queue>
      6 #include<vector>
      7 #include<cmath>
      8 #include<string>
      9 #include<map>
     10 
     11 using namespace std;
     12 #define int long long 
     13 const int maxn=128;
     14 
     15 char str1[1010][100]; 
     16 char str2[2000005];
     17 
     18 char STR[1003][66];
     19 char SSS[2000100];
     20 struct Trie{
     21     int next[2010*50][maxn];
     22     int fail[2010*50],end[2010*50];
     23     int root,L;
     24     int newnode() //初始化 
     25     {
     26         for(int i=0;i<128;i++)
     27         next[L][i]=-1;
     28         end[L++]=-1;
     29         return L-1;
     30     }
     31 
     32     void init()//初始化 
     33     {
     34         L=0;
     35         root=newnode();
     36     }
     37     void insert(char s[],int id)//构造树trie 
     38     {
     39         int len=strlen(s);
     40         int now=root;
     41         for(int i=0;i<len;i++)
     42         {
     43             if(next[now][s[i]]==-1)
     44               next[now][s[i]]=newnode();
     45             now=next[now][s[i]];  
     46         }
     47         end[now]=id;//记录单词的id
     48     }
     49 
     50     void build()//构造失败指针 
     51     {
     52         queue<int>Q;
     53         fail[root]=root;
     54         for(int i=0;i<128;i++)
     55         if(next[root][i]==-1)
     56             next[root][i]=root;
     57         else
     58         {
     59             fail[next[root][i]]=root;
     60             Q.push(next[root][i]);
     61         }
     62         while(!Q.empty())
     63         {
     64             int now=Q.front();
     65             Q.pop();
     66             for(int i=0;i<128;i++)
     67                 if(next[now][i]==-1)
     68                     next[now][i]=next[fail[now]][i];
     69                     else
     70                     {
     71                         fail[next[now][i]]=next[fail[now]][i];
     72                         Q.push(next[now][i]);
     73                     }
     74 
     75                 }       
     76     }
     77 
     78 
     79   int vis[1666];//记录出现的次数
     80   void  query(char buf[],int n)//查询 
     81   {
     82     int len=strlen(buf);
     83     int now=root;
     84     memset(vis,0,sizeof(vis));
     85     bool flag=false;
     86     for(int i=0;i<len;i++)
     87     {
     88             now = next[now][buf[i]];
     89             int temp = now;
     90             while(temp != root)
     91             {
     92                 if(end[temp] != -1)
     93                 {
     94                     vis[end[temp]]++;
     95                     flag = true;
     96                 }
     97                 temp = fail[temp];
     98             }
     99       }
    100       if(flag ){
    101           for(int i=1;i<=n;i++){
    102           if(vis[i]){
    103               printf("%s: %lld
    ",STR[i],vis[i]);    
    104         }
    105       }
    106       }
    107       return ;
    108       
    109       
    110     }
    111 }AC;
    112 
    113 signed  main(){
    114     int n;
    115     
    116     while(~scanf("%lld",&n)){
    117      
    118     AC.init();
    119     for(int i=1;i<=n;i++){
    120         scanf("%s",STR[i]);
    121         AC.insert(STR[i],i);
    122     }
    123     AC.build();
    124     scanf("%s",SSS);
    125     AC.query(SSS,n); 
    126     } 
    127     return 0; 
    128 }
  • 相关阅读:
    前端面试的一道数组元素值去重问题
    数组元素前移,第一个元素放置数组末位
    Linux 查询oracle错误日志&警告日志
    CentOS 6.4 源码安装MySQL 5.6
    Oracle 表空间不足引起的问题及解决方法
    Oracle 强制中止正在执行的SQL语句
    request for member 'GetByteArrayElements'
    jni入门 eclipsecygwin+ndk
    ffmpeg结构体(二)
    ffmpeg结构体(三)
  • 原文地址:https://www.cnblogs.com/pengge666/p/12207713.html
Copyright © 2020-2023  润新知