zoukankan      html  css  js  c++  java
  • AC自动机 专题

      1 // 求目标串中出现了几个模式串
      2 //====================
      3 #include <stdio.h>
      4 #include <algorithm>
      5 #include <iostream>
      6 #include <string.h>
      7 #include <queue>
      8 using namespace std;
      9 
     10 struct Trie
     11 {
     12     int next[500010][26],fail[500010],end[500010];
     13     int root,L;
     14     int newnode()
     15     {
     16         for(int i = 0;i < 26;i++)
     17             next[L][i] = -1;
     18         end[L++] = 0;
     19         return L-1;
     20     }
     21     void init()
     22     {
     23         L = 0;
     24         root = newnode();
     25     }
     26     void insert(char buf[])
     27     {
     28         int len = strlen(buf);
     29         int now = root;
     30         for(int i = 0;i < len;i++)
     31         {
     32             if(next[now][buf[i]-'a'] == -1)
     33                 next[now][buf[i]-'a'] = newnode();
     34             now = next[now][buf[i]-'a'];
     35         }
     36         end[now]++;
     37     }
     38     void build()
     39     {
     40         queue<int>Q;
     41         fail[root] = root;
     42         for(int i = 0;i < 26;i++)
     43             if(next[root][i] == -1)
     44                 next[root][i] = root;
     45             else
     46             {
     47                 fail[next[root][i]] = root;
     48                 Q.push(next[root][i]);
     49             }
     50         while( !Q.empty() )
     51         {
     52             int now = Q.front();
     53             Q.pop();
     54             for(int i = 0;i < 26;i++)
     55                 if(next[now][i] == -1)
     56                     next[now][i] = next[fail[now]][i];
     57                 else
     58                 {
     59                     fail[next[now][i]]=next[fail[now]][i];
     60                     Q.push(next[now][i]);
     61                 }
     62         }
     63     }
     64     int query(char buf[])
     65     {
     66         int len = strlen(buf);
     67         int now = root;
     68         int res = 0;
     69         for(int i = 0;i < len;i++)
     70         {
     71             now = next[now][buf[i]-'a'];
     72             int temp = now;
     73             while( temp != root )
     74             {
     75                 res += end[temp];
     76                 end[temp] = 0;
     77                 temp = fail[temp];
     78             }
     79         }
     80         return res;
     81     }
     82     void debug()
     83     {
     84         for(int i = 0;i < L;i++)
     85         {
     86             printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],end[i]);
     87             for(int j = 0;j < 26;j++)
     88                 printf("%2d",next[i][j]);
     89             printf("]
    ");
     90         }
     91     }
     92 };
     93 char buf[1000010];
     94 Trie ac;
     95 int main()
     96 {
     97     int T;
     98     int n;
     99     scanf("%d",&T);
    100     while( T-- )
    101     {
    102         scanf("%d",&n);
    103         ac.init();
    104         for(int i = 0;i < n;i++)
    105         {
    106             scanf("%s",buf);
    107             ac.insert(buf);
    108         }
    109         ac.build();
    110         scanf("%s",buf);
    111         printf("%d
    ",ac.query(buf));
    112     }
    113     return 0;
    114 }
    //输出每个模式串出现的次数
    
    
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <queue>
    using namespace std;
    
    char str[1010][100];
    struct Trie
    {
        int next[1010*50][128],fail[1010*50],end[1010*50];
        int root,L;
        int newnode()
        {
            for(int i = 0;i < 128;i++)
                next[L][i] = -1;
            end[L++] = -1;
            return L-1;
        }
        void init()
        {
            L = 0;
            root = newnode();
        }
        void insert(char s[],int id)
        {
            int len = strlen(s);
            int now = root;
            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 < 128;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 < 128;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[1010];
        void query(char buf[],int n)
        {
            for(int i = 0;i < n;i++)
                num[i] = 0;
            int len=strlen(buf);
            int now=root;
            for(int i=0;i<len;i++)
            {
                now=next[now][buf[i]];
                int temp = now;
                while( temp != root )
                {
                    if(end[temp] != -1)
                        num[end[temp]]++;
                    temp = fail[temp];
                }
            }
            for(int i = 0;i < n;i++)
                if(num[i] > 0)
                    printf("%s: %d
    ",str[i],num[i]);
        }
    
    };
    
    char buf[2000010];
    Trie ac;
    void debug()
    {
        for (int i = 0; i < ac.L; i++)
        {
            printf("id = %3d ,fail = %3d ,end = %3d, chi = [",i,ac.fail[i],ac.end[i]);
            for (int j = 0; j < 128; j++)
                printf("%2d ",ac.next[i][j]);
            printf("]
    ");
        }
    }
    int main()
    {
    //    freopen("in.txt","r",stdin);
    //    freopen("out.txt","w",stdout);
        int n;
        while(scanf("%d",&n) == 1)
        {
            ac.init();
            for(int i = 0;i < n;i++)
            {
                scanf("%s",str[i]);
                ac.insert(str[i],i);
            }
            ac.build();
            scanf("%s",buf);
            ac.query(buf,n);
        }
        return 0;
    }

    转自bin神 orz

  • 相关阅读:
    【python cookbook学习笔记】给字典增加一个条目
    UI设计星级评价
    弱引用和循环引用
    lua数据类型
    lua虚拟机笔记
    c++对象模型笔记
    使树控件方向键无效
    实现CListCtrl自定义行高
    创建对话框时常用配置
    C++格式化输出总结
  • 原文地址:https://www.cnblogs.com/tsw123/p/4449203.html
Copyright © 2011-2022 走看看