• hdu 2896 病毒侵袭 ac自动机


      1 /*
      2 hdu 2896 病毒侵袭 ac自动机 
      3 从题意得知,模式串中没有重复的串出现,所以结构体中可以将last[](后缀链接)数组去掉 
      4 last[]数组主要是记录具有相同后缀模式串的末尾节点编号 。本题中主要是计算每一个模式串
      5 在主串中有没有出现过,而不是计算出现过多少次,所以将last[]数组省掉.... 
      6 */ 
      7 #include<algorithm>
      8 #include<iostream>
      9 #include<cstdio>
     10 #include<cstring>
     11 #include<queue> 
     12 #define N 210*500
     13 using namespace std;
     14 class AC_atomata
     15 {
     16 public:
     17    int trie[N][128],  f[N], val[N];
     18    int vis[510];
     19    int nodeN;
     20    int total;
     21    queue<int>q;
     22    void init()
     23    {
     24       nodeN=0;
     25       val[0]=0;
     26       total=0;
     27       while(!q.empty()) q.pop();
     28       memset(trie[0], 0, sizeof(trie[0]));
     29    }
     30    void build(char *str, int index);//建立trie树 
     31    void getFail();//失配函数 
     32    void find(char *T, int n, int index);//查找函数 
     33 };
     34 
     35 
     36 void AC_atomata::build(char *str, int index)
     37 {
     38     int i, u;
     39     for(i=0, u=0; str[i]; ++i)
     40     {
     41         int ch=str[i];
     42         if(!trie[u][ch])
     43         {
     44             trie[u][ch]=++nodeN;
     45             memset(trie[nodeN], 0, sizeof(trie[nodeN]));
     46     }
     47     u=trie[u][ch];
     48     val[u]=0;
     49     }
     50     val[u]=index;
     51 }
     52 
     53 void AC_atomata::getFail()
     54 {
     55    int r, u, v, i;
     56    f[0]=0;
     57    for(i=0; i<128; ++i)
     58    {
     59        if(trie[0][i])
     60        {
     61              q.push(trie[0][i]);
     62              f[trie[0][i]]=0;
     63        }
     64    }
     65    while(!q.empty())
     66    {
     67       r=q.front();
     68       q.pop();
     69       for(i=0; i<128; ++i)
     70       {
     71             u=trie[r][i];
     72             if(!u) continue;
     73             q.push(u);
     74             v=f[r];
     75             while(v && !trie[v][i]) v=trie[v][i];
     76             f[u]=trie[v][i];
     77       }
     78    }
     79 }
     80 
     81 void AC_atomata::find(char *T, int n, int index)
     82 {
     83     int i, u;
     84     int cnt=0, v[3];
     85     memset(v, 0, sizeof(v));
     86     memset(vis, 0, sizeof(vis));//每一次查找将数组初始化,开始忘记初始化了, 哇了好多次 
     87     for(i=0, u=0; T[i]; ++i)
     88     {
     89         int ch=T[i];
     90         while(u && !trie[u][ch])  u=f[u];
     91         u=trie[u][ch];
     92         if(val[u] && !vis[val[u]])
     93         {
     94             v[cnt++]=val[u];
     95             vis[val[u]]=1;
     96             if(cnt>2) break;
     97         }
     98     }
     99     if(cnt>0)
    100     {
    101         ++total;
    102         printf("web %d:", index);
    103         sort(v, v+3);
    104         for(i=0; i<3; ++i)
    105            if(v[i])  printf(" %d", v[i]);
    106         printf("
    ");
    107     }
    108 }
    109 
    110 AC_atomata ac;
    111 char T[10005], s[205];
    112 
    113 int main()
    114 {
    115    int n, m, i;
    116    while(scanf("%d", &n)!=EOF)
    117    {
    118        ac.init();
    119        for(i=1; i<=n; ++i)
    120         {
    121            scanf("%s", s);
    122            ac.build(s, i);
    123     }
    124        ac.getFail();
    125        scanf("%d", &m);
    126        for(i=1; i<=m; ++i)
    127        {
    128              scanf("%s", T);
    129              ac.find(T, n, i);
    130        }
    131        printf("total: %d
    ", ac.total);
    132    }
    133    return 0;
    134 } 
      1 /*
      2     上面的程序过了,感觉数据很水....
      3 */
      4 #include<iostream>
      5 #include<cstdio>
      6 #include<cstring>
      7 #include<queue>
      8 #define N 100005 
      9 #define M 505
     10 using namespace std;
     11 int n, m;
     12 class AC_atomata
     13 { 
     14 public:
     15     int trie[N][128], fail[N];
     16     int cnt;
     17     int vis[M];//标记边 
     18     int nodeN;//节点数 
     19     int val[N];//标记字符节点是否为单词末尾 
     20     queue<int>q;
     21     void init();
     22     void build(char *T, int index) ;
     23     void getFail();
     24     void find(char *S, int index);
     25 };
     26 
     27 void AC_atomata:: init()
     28 {
     29    while(!q.empty())  q.pop();
     30    memset(trie[0], 0, sizeof(trie[0]));
     31    nodeN=0;
     32    cnt=0;
     33    memset(val, 0, sizeof(val));
     34 }
     35 
     36 void AC_atomata:: build(char *T, int index)
     37 {
     38     int i, u=0;
     39     for(i=0; T[i]; ++i)
     40     {
     41         if(trie[u][T[i]]==0)
     42         {
     43             trie[u][T[i]]=++nodeN;
     44             memset(trie[nodeN], 0, sizeof(trie[nodeN]));
     45     }
     46     val[u]=0;
     47     u=trie[u][T[i]];
     48     }
     49     val[u]=index;
     50 }
     51 
     52 void AC_atomata:: getFail()
     53 { 
     54     int r, u, v; 
     55     int c, root=0;
     56     fail[root]=0;
     57     for(c=0; c<128; ++c)
     58     {
     59         if(v=trie[root][c])
     60         {
     61             fail[v]=root;
     62             q.push(v);
     63     }
     64     }
     65     while(!q.empty())
     66     {
     67         r=q.front(); q.pop();
     68     for(c=0; c<128; ++c)
     69     {
     70         u=trie[r][c];
     71         if(!u)//该节点不存在,也就是查找过程中每一个节点都是平等的
     72            trie[r][c]=trie[fail[r]][c];
     73         else
     74         {
     75             fail[u]=trie[fail[r]][c];
     76             q.push(u);
     77         }
     78     } 
     79     } 
     80 } 
     81 
     82 void AC_atomata:: find(char *S, int index)
     83 {
     84    int cur, root, count=0;
     85    cur=root=0;
     86    memset(vis, 0, sizeof(vis));
     87    for(int i=0; S[i]; ++i)
     88    {
     89        cur=trie[cur][S[i]];
     90        int next=cur;

              //这个while循环就是last[]数组实现的功能,只不过是last[]数组记录的总是单词结尾字符的节点的编号
              //而我们通过沿着 next 节点的失配方向一直搜索, 也可以寻找到 以next节点所对应字符结尾的单词

     91        while(next!=root)
     92        {
     93               if(val[next])
     94                  {
     95               vis[val[next]]=1;
     96               count++;
     97           }
     98               next=fail[next];
     99        } 
    100    }
    101    if(count>0)
    102    {
    103        ++cnt;
    104        printf("web %d:", index);
    105        for(int i=1; i<=n; ++i)
    106          if(vis[i])
    107            printf(" %d", i);
    108        printf("
    ");
    109    }
    110 } 
    111 
    112 char t[205], s[10005];
    113 AC_atomata ac;
    114 int main()
    115 {   
    116    int i;
    117    while(scanf("%d", &n)!=EOF)
    118    {
    119        ac.init();
    120        for(i=1; i<=n; ++i) 
    121        {
    122              scanf("%s", t);
    123              ac.build(t, i);
    124        }
    125        ac.getFail();
    126        scanf("%d", &m) ;
    127        for(i=1; i<=m; ++i)
    128        {
    129              scanf("%s", s);
    130              ac.find(s, i);
    131        }
    132        printf("total: %d
    ", ac.cnt);
    133    }
    134    return 0;
    135 }
  • 相关阅读:
    IDEA 快捷键
    Python3开启自带http服务
    redis-creating server tcp listening socket 127.0.0.1:6379: bind No error
    moco的使用方法
    tomcat程序闪退,如何让tomcat不闪退,可以看见报错
    java 项目中Error linstenerStart 报错解决方法
    Linux 常用命令
    TS数据类型及语法
    RabbitMQ的下载和安装
    vue 控制 input 的 disabled
  • 原文地址:https://www.cnblogs.com/hujunzheng/p/3801731.html
Copyright © 2020-2023  润新知