hdu 2896 病毒侵袭 ac自动机

简介:
/*
hdu 2896 病毒侵袭 ac自动机 
从题意得知,模式串中没有重复的串出现,所以结构体中可以将last[](后缀链接)数组去掉 
last[]数组主要是记录具有相同后缀模式串的末尾节点编号 。本题中主要是计算每一个模式串
在主串中有没有出现过,而不是计算出现过多少次,所以将last[]数组省掉.... 
*/ 
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue> 
#define N 210*500
using namespace std;
class AC_atomata
{
public:
   int trie[N][128],  f[N], val[N];
   int vis[510];
   int nodeN;
   int total;
   queue<int>q;
   void init()
   {
      nodeN=0;
      val[0]=0;
      total=0;
      while(!q.empty()) q.pop();
      memset(trie[0], 0, sizeof(trie[0]));
   }
   void build(char *str, int index);//建立trie树 
   void getFail();//失配函数 
   void find(char *T, int n, int index);//查找函数 
};


void AC_atomata::build(char *str, int index)
{
    int i, u;
    for(i=0, u=0; str[i]; ++i)
    {
        int ch=str[i];
        if(!trie[u][ch])
        {
            trie[u][ch]=++nodeN;
            memset(trie[nodeN], 0, sizeof(trie[nodeN]));
    }
    u=trie[u][ch];
    val[u]=0;
    }
    val[u]=index;
}

void AC_atomata::getFail()
{
   int r, u, v, i;
   f[0]=0;
   for(i=0; i<128; ++i)
   {
       if(trie[0][i])
       {
             q.push(trie[0][i]);
             f[trie[0][i]]=0;
       }
   }
   while(!q.empty())
   {
      r=q.front();
      q.pop();
      for(i=0; i<128; ++i)
      {
            u=trie[r][i];
            if(!u) continue;
            q.push(u);
            v=f[r];
            while(v && !trie[v][i]) v=trie[v][i];
            f[u]=trie[v][i];
      }
   }
}

void AC_atomata::find(char *T, int n, int index)
{
    int i, u;
    int cnt=0, v[3];
    memset(v, 0, sizeof(v));
    memset(vis, 0, sizeof(vis));//每一次查找将数组初始化,开始忘记初始化了, 哇了好多次 
    for(i=0, u=0; T[i]; ++i)
    {
        int ch=T[i];
        while(u && !trie[u][ch])  u=f[u];
        u=trie[u][ch];
        if(val[u] && !vis[val[u]])
        {
            v[cnt++]=val[u];
            vis[val[u]]=1;
            if(cnt>2) break;
        }
    }
    if(cnt>0)
    {
        ++total;
        printf("web %d:", index);
        sort(v, v+3);
        for(i=0; i<3; ++i)
           if(v[i])  printf(" %d", v[i]);
        printf("\n");
    }
}

AC_atomata ac;
char T[10005], s[205];

int main()
{
   int n, m, i;
   while(scanf("%d", &n)!=EOF)
   {
       ac.init();
       for(i=1; i<=n; ++i)
        {
           scanf("%s", s);
           ac.build(s, i);
    }
       ac.getFail();
       scanf("%d", &m);
       for(i=1; i<=m; ++i)
       {
             scanf("%s", T);
             ac.find(T, n, i);
       }
       printf("total: %d\n", ac.total);
   }
   return 0;
/*
    上面的程序过了,感觉数据很水....
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define N 100005 
#define M 505
using namespace std;
int n, m;
class AC_atomata
public:
    int trie[N][128], fail[N];
    int cnt;
    int vis[M];//标记边 
    int nodeN;//节点数 
    int val[N];//标记字符节点是否为单词末尾 
    queue<int>q;
    void init();
    void build(char *T, int index) ;
    void getFail();
    void find(char *S, int index);
};

void AC_atomata:: init()
{
   while(!q.empty())  q.pop();
   memset(trie[0], 0, sizeof(trie[0]));
   nodeN=0;
   cnt=0;
   memset(val, 0, sizeof(val));
}

void AC_atomata:: build(char *T, int index)
{
    int i, u=0;
    for(i=0; T[i]; ++i)
    {
        if(trie[u][T[i]]==0)
        {
            trie[u][T[i]]=++nodeN;
            memset(trie[nodeN], 0, sizeof(trie[nodeN]));
    }
    val[u]=0;
    u=trie[u][T[i]];
    }
    val[u]=index;
}

void AC_atomata:: getFail()
    int r, u, v; 
    int c, root=0;
    fail[root]=0;
    for(c=0; c<128; ++c)
    {
        if(v=trie[root][c])
        {
            fail[v]=root;
            q.push(v);
    }
    }
    while(!q.empty())
    {
        r=q.front(); q.pop();
    for(c=0; c<128; ++c)
    {
        u=trie[r][c];
        if(!u)//该节点不存在,也就是查找过程中每一个节点都是平等的
           trie[r][c]=trie[fail[r]][c];
        else
        {
            fail[u]=trie[fail[r]][c];
            q.push(u);
        }
    } 
    } 

void AC_atomata:: find(char *S, int index)
{
   int cur, root, count=0;
   cur=root=0;
   memset(vis, 0, sizeof(vis));
   for(int i=0; S[i]; ++i)
   {
       cur=trie[cur][S[i]];
       int next=cur;

          //这个while循环就是last[]数组实现的功能,只不过是last[]数组记录的总是单词结尾字符的节点的编号
          //而我们通过沿着 next 节点的失配方向一直搜索, 也可以寻找到 以next节点所对应字符结尾的单词
       while(next!=root)
       {
              if(val[next])
                 {
              vis[val[next]]=1;
              count++;
          }
              next=fail[next];
       } 
   }
   if(count>0)
   {
       ++cnt;
       printf("web %d:", index);
       for(int i=1; i<=n; ++i)
         if(vis[i])
           printf(" %d", i);
       printf("\n");
   }

char t[205], s[10005];
AC_atomata ac;
int main()
{   
   int i;
   while(scanf("%d", &n)!=EOF)
   {
       ac.init();
       for(i=1; i<=n; ++i) 
       {
             scanf("%s", t);
             ac.build(t, i);
       }
       ac.getFail();
       scanf("%d", &m) ;
       for(i=1; i<=m; ++i)
       {
             scanf("%s", s);
             ac.find(s, i);
       }
       printf("total: %d\n", ac.cnt);
   }
   return 0;
}









本文转自 小眼儿 博客园博客,原文链接:http://www.cnblogs.com/hujunzheng/p/3801731.html,如需转载请自行联系原作者
目录
相关文章
|
SQL Oracle Java
Java 生态圈中的嵌入式数据库,哪家强?(上)
嵌入式数据库一个很陌生的词汇,以前只是听说,但是没有真正使用过,今天小编和大家一起来揭开它的面纱。
Java 生态圈中的嵌入式数据库,哪家强?(上)
|
10月前
|
机器学习/深度学习 人工智能 自然语言处理
280页PDF,全方位评估OpenAI o1,Leetcode刷题准确率竟这么高
【10月更文挑战第24天】近年来,OpenAI的o1模型在大型语言模型(LLMs)中脱颖而出,展现出卓越的推理能力和知识整合能力。基于Transformer架构,o1模型采用了链式思维和强化学习等先进技术,显著提升了其在编程竞赛、医学影像报告生成、数学问题解决、自然语言推理和芯片设计等领域的表现。本文将全面评估o1模型的性能及其对AI研究和应用的潜在影响。
241 1
|
9月前
|
机器学习/深度学习 Shell 网络安全
【Git】Git 命令参考手册
Git 命令参考手册的扩展部分,包含了从基础操作到高级功能的全面讲解。
227 3
|
XML 数据可视化 NoSQL
【软件设计师备考 专题 】数据模型,ER图,第一范式、第二范式、第三范式
【软件设计师备考 专题 】数据模型,ER图,第一范式、第二范式、第三范式
279 0
|
机器学习/深度学习 编解码 人工智能
论文精读 TransGAN:两个纯粹的Transformer可以组成一个强大的GAN(TransGAN:Two Pure Transformers Can Make One Strong GAN)
TransGAN是UT-Austin、加州大学、 IBM研究院的华人博士生构建了一个只使用纯 transformer 架构、完全没有卷积的 GAN,并将其命名为 TransGAN。该论文已被NeruIPS(Conference and Workshop on Neural Information Processing Systems,计算机人工智能领域A类会议)录用,文章发表于2021年12月。 该文章旨在仅使用Transformer网络设计GAN。Can we build a strong GAN completely free of convolutions? 论文地址:https://
论文精读 TransGAN:两个纯粹的Transformer可以组成一个强大的GAN(TransGAN:Two Pure Transformers Can Make One Strong GAN)
|
文字识别 索引
Halcon 学习笔记七:文字识别案例
Halcon 学习笔记七:文字识别案例
313 0
|
Java 微服务
Malformed markup: Attribute “prop“ appears more than once in element
Malformed markup: Attribute “prop“ appears more than once in element
449 0
|
弹性计算
阿里云服务器开放所有端口
阿里云服务器开放所有端口,阿里云服务器端口怎么全部打开?在安全组中开启端口号,在安全组中把端口范围设置为-1/-1,授权对象填0.0.0.0/0,即可开通全部端口号,阿腾云来详细说下阿里云服务器端口全部打开教程:
1407 0
|
设计模式 C# uml
UML类图及C#实现
我们引用《大话设计模式》中得UML类图图示样例来学习UML类图。 本文UML类图使用了Visual Paradigm工具绘制。 UML视图主要可以帮我们理清楚思路:知道每个对象直接的交互关系,而且让我们更加清楚的知道什么时候用什么结构。
UML类图及C#实现
|
移动开发 应用服务中间件 定位技术
实战!使用pano2vr生成html5全景页面
随着现代视觉技术的进步以及对空间展示的迫切需求,很多的无人机可以拍出360度甚至720度全景照片,怎样将全景地图以html5的形式展示出来?文章将详细讲解如何使用pano2vr.exe制作全景页面。
1063 0
实战!使用pano2vr生成html5全景页面