NYOJ 1085 AC自动机基础模板

今天学了AC自动机,可以说AC自动机是把匹配的串建立成为一颗trie,然后就和kmp 是一样的

题意:判断在一篇文章中有多少单词出现过,并输出来

#include<cstdio>
#include<cstring>
#include<map>
#include<queue>
#include<iostream>
using namespace std;
const int maxn = 1000007;
int cnt;
struct Node{
    Node *fail;
    Node *next[27];
    int count,id;
    Node(){
        memset(next,NULL,sizeof(next));
        fail = NULL;
        count = 0 ,id = -1;
    }
};
char word[200][108];
int keymap[200],ret[200];
char str[maxn];
int Max;
void insert(int pos,char *str,Node *root){
    Node *p = root;
    int i=0,index;
    while(str[i]){
        index = str[i] - 'a';
        if(p -> next[index] == NULL)
            p -> next[index] = new Node();
        p = p->next[index];i++;
    }
    if(!p->count){
        p->id = cnt++;
        p ->count = 1;
    } keymap[pos] = p->id;
}
void Build_AC_auto(Node *root){
    queue <Node*> s;
    root -> fail = NULL;
    s.push (root);
    while(!s.empty()){
        Node *tmp = s.front();s.pop();
        Node *p   = NULL;
        for(int i=0;i<26;i++){
            if(tmp ->next[i]){
                if(tmp == root)tmp->next[i]->fail = root;
                else {
                    p = tmp->fail;
                    while(p){
                        if(p->next[i]){
                            tmp -> next[i] -> fail = p -> next[i];
                            break;
                        }
                        p = p -> fail;
                    }
                    if(!p)tmp->next[i]->fail = root;
                }
                s.push(tmp -> next[i]);
            }
        }
    }
}
void query(Node *root){
    int i=0;
    Node *p = root;
    while(str[i]){
        int index = str[i] - 'a';
        while(!p->next[index] && p!=root)p = p->fail;
        p = p->next[index];
        p = (p == NULL) ? root : p;
        Node *tmp = p;
        while(tmp !=root ){//puts("yes");
            if(tmp ->count){
               ret[tmp ->id]++;
               if(ret[tmp ->id]> Max){
                Max = ret[tmp -> id];
               }
            }
            tmp = tmp->fail;
        }
        i++;
    }
}
int main(){
    int t,n,m;
    freopen("input.txt","r",stdin);
    scanf("%d",&t);
    while(t --){
        Max = 0;cnt =0 ;
        Node *root = new Node();
        scanf("%d",&n);
       memset(ret,0,sizeof(ret));
       for(int i=0;i<n;i++){
            scanf("%s",word[i]);
            insert(i,word[i],root);
       }
        Build_AC_auto(root);
        scanf("%s",str);
        query(root);
        printf("%d\n",Max);
        for(int i=0;i<n;i++){
            if(ret[keymap[i]]== Max){
                printf("%s\n",word[i]);
            }
        }
    }
}
时间: 2024-11-13 02:36:45

NYOJ 1085 AC自动机基础模板的相关文章

ac自动机基础模板(hdu2222)

In the modern time, Search engine came into the life of everybody like Google, Baidu, etc. Wiskey also wants to bring this feature to his image retrieval system. Every image have a long description, when users type some keywords to find the image, th

HDU 2222 Keywords Search (AC自动机入门 模板)

AC自动机入门 Aho-Corasick automaton,该算法在1975年产生于贝尔实验室,是著名的多模匹配算法之一.学习AC自动机之前得先有Trie树和KMP模式匹配算法的基础. AC自动机算法分为3步:1.构造一棵tire树  2.构造失败指针  3.进行模式匹配 AC自动机的优化:Trie图 Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other

AC自动机基础

AC自动机不是自动AC机 简介 看dalao们AC自动机的Blog,大多数奆奆都会感性地说: AC_automation = KMP+TRIE 然而在我重蹈覆辙辗转反侧n次后才明白,这东西说了等于没说. AC自动机是一种有限状态自动机(说了等于没说),它常被用于多模式串的字符串匹配. 在学完AC自动机,我也总结出一句说了等于没说的话: AC自动机是以TRIE的结构为基础,结合KMP的思想建立的. 建立AC自动机 建立一个AC自动机通常需要两个步骤: 基础的TRIE结构:将所有的模式串构成一棵Tr

[hdu2222]ac自动机(模板)

题意:一个文本串+多个模板串的匹配问题 思路:裸的ac自动机. 1 #pragma comment(linker, "/STACK:10240000,10240000") 2 3 #include <iostream> 4 #include <cstdio> 5 #include <algorithm> 6 #include <cstdlib> 7 #include <cstring> 8 #include <map&g

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]

hdoj 2896 病毒侵袭 【AC自动机 基础题】

病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 15893    Accepted Submission(s): 4055 Problem Description 当太阳的光辉逐渐被月亮遮蔽,世界失去了光明,大地迎来最黑暗的时刻....在这样的时刻,人们却异常兴奋--我们能在有生之年看到500年一遇的世界奇观,那是多么幸福的事

hdoj 3065 病毒侵袭持续中 【AC自动机 基础题】【输出每个模式串出现的次数】

病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 8678    Accepted Submission(s): 3045 Problem Description 小t非常感谢大家帮忙解决了他的上一个问题.然而病毒侵袭持续中.在小t的不懈努力下,他发现了网路中的"万恶之源".这是一个庞大的病毒网站,他有着好多好多

【hdu2222-Keywords Search】AC自动机基础裸题

http://acm.hust.edu.cn/vjudge/problem/16403 题意:给定n个单词,一个字符串,问字符串中出现了多少个单词.(若单词her,he,字符串aher中出现了两个单词) 题解: 每个单词末尾节点sum=1:find的时候每个点都顺着fail往上跳,加上该节点的sum,然后将这个sum清了:注意同一个单词出现多次只算一次. 1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring>

Keywords Search---hdu2222(AC自动机 模板)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222 一个常见的例子就是给出n个单词,再给出一段包含m个字符的文章,让你找出有多少个单词在文章里出现过: 本题就是最基础的模板:在此之前需要理解kmp和字典树(trie); Trie树有3个基本性质: (1) 根节点不包含字符,除根节点外每一个节点都只包含一个字符: (2) 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串: (3) 每个节点的所有子节点包含的字符都不相同. 1.