zoukankan      html  css  js  c++  java
  • Keywords Search

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #include <iostream>
      5 using namespace std;
      6 
      7 const int kind=26;
      8 
      9 struct node {
     10     node *fail;     //失败指针
     11     node *next[kind];//Tire树每个节点的子节点个数
     12     int cot;        //是否为该单词的最后一个节点
     13     node()          //构造函数初始化
     14     {
     15         fail=NULL;
     16         cot=0;
     17         memset(next,0,sizeof(next));
     18     }
     19 }*q[500002];        //队列,方便用于bfs构造失败指针
     20 char str[1000001];  //模式串
     21 int head,tail;      //队列的头尾指针
     22 
     23 
     24 void inser(char *str,node *root)        //构造tire数;
     25 {
     26     node *p=root;
     27     int i=0,index;
     28     while(str[i])
     29     {
     30         index=str[i]-'a';
     31         if(p->next[index]==NULL)
     32             p->next[index]=new node();
     33         p=p->next[index];       //p指向i字符相等的节点
     34         i++;
     35     }
     36     p->cot++;       //在单词的最后一个节点是的cot加1,代表单词数加1;
     37 }
     38 
     39 void build_ac_automatio(node *root)         //写出fail的指向
     40 {
     41     int i;
     42     root->fail=NULL;
     43     q[head++]=root;             //bfs
     44     while(head!=tail)
     45     {
     46         node *temp=q[tail++];
     47         node *p=NULL;
     48         for(i=0;i<26;i++)
     49         {
     50             if(temp->next[i]!=NULL)         //当前的子节点i不为空
     51             {
     52                 if(temp==root)
     53                     temp->next[i]->fail=root;
     54                 else
     55                 {
     56                     p=temp->fail;               //记录一下当前节点失败节点指向那个节点
     57                     while(p!=NULL)              //直到找到
     58                     {
     59                         if(p->next[i]!=NULL)        //失败节点指向的节点的i子节点不为空的话,就和当前节点的i相等,即当前i的失败节点即为父节点失败节点指向的i子节点、
     60                         {
     61                             temp->next[i]->fail=p->next[i]; break;
     62                         }
     63                         p=p->fail;
     64                     }
     65                     if(p==NULL)
     66                         temp->next[i]->fail=root;
     67                 }
     68                q[head++]=temp->next[i];         //先把失败节点指向,再进入队列
     69             }
     70         }
     71     }
     72 }
     73 
     74 
     75 int query(node *root)           //查询
     76 {
     77     int i=0,cnt=0,index,len=strlen(str);
     78     node *p=root;
     79     
     80     while(str[i])
     81     {
     82         index =str[i]-'a';
     83         while(p->next[index]==NULL&&p!=root)        //当前节点失败,&& 第root节点
     84             p=p->fail;
     85         p=p->next[index];
     86         p=(p==NULL)?root:p;
     87         node *temp=p;
     88         while(temp!=root&&temp->cot!=-1)        //查询当前字符节点是否为结束字符, && 单词之前没有
     89         {
     90             cnt+=temp->cot;
     91             if(temp->cot>0)
     92                 temp->cot=-1;
     93             temp=temp->fail;
     94         }
     95         i++;
     96     }
     97     return cnt;
     98 }
     99 
    100 int main()
    101 {
    102     int t,n,i;
    103     char s[51];
    104     scanf("%d",&t);
    105     while(t--)
    106     {
    107         node root;
    108         scanf("%d",&n);
    109         for( i=0;i<n;i++)
    110         {
    111             //gets(s);
    112             scanf("%s",s);
    113             //getchar();
    114             inser(s,&root);
    115         }
    116         build_ac_automatio(&root);
    117         scanf("%s",str);
    118         printf("%d
    ",query(&root));
    119     }
    120     return 0;
    121 }
    122         
    View Code

    AC自动机

    Sample Input
    1
    5
    she
    he
    say
    shr
    her
    yasherhs
     
    Sample Output
    3

    有多个单词,在主串中出现过多少个单词、

    构建字典树,建立fail指针直到求出结果

  • 相关阅读:
    Zookeeper C API 指南六(异步 API 介绍)
    libuv 中文编程指南(三)文件系统
    Zookeeper C API 指南二(监视(Wathes), 基本常量和结构体介绍)
    Zookeeper C API 指南五(同步 API 介绍)
    Zookeeper C API 指南七(Zookeeper 辅助 API 介绍)
    libuv 中文编程指南(四)网络
    Zookeeper C API 指南八(Zookeeper C API 应用示例)
    Zookeeper C API 指南四(C API 概览)
    Zookeeper C API 指南三(回调函数)
    jQuery Mobile 移动开发中的日期插件Mobiscroll 2.3 使用说明
  • 原文地址:https://www.cnblogs.com/WDKER/p/5422273.html
Copyright © 2011-2022 走看看