【UVA】1449-Dominating Patterns(AC自己主动机)

AC自己主动机的模板题。须要注意的是,对于每一个字符串,须要利用map将它映射到一个结点上,这样才干按顺序输出结果。

14360841 1449 option=com_onlinejudge&Itemid=8&page=show_problem&problem=4195" style="font-size:13.3333330154419px; margin:0px; padding:0px; color:rgb(153,0,0); text-decoration:none">Dominating Patterns Accepted C++ 0.146 2014-10-16 11:41:35

#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 150 * 75;
const int len  = 1111111;
const int max_size = 26;
char str[155][75];
char _str[len];
struct Trie{ //AC
    int tr[maxn][max_size];
    int fail[maxn];
    int val[maxn];     //结果
    int sz,root,_max;  //出现次数
    map<int,int>countx;//计算第i个字符串出现的次数
    map<string,int>vis;
    int index(char c){
        return c - 'a';
    }
    int newnode(){
        val[sz] = 0;
        for(int i = 0; i < 26; i++) tr[sz][i] = -1;
        sz ++;
        return sz - 1;
    }
    void init(){
        sz = 0;_max = 0;
        root = newnode();
        countx.clear();
        vis.clear();
    }
    void insert(char *s,int id){
         int u = root;
         int n = strlen(s);
         for(int i = 0; i < n; i++){
              int c = index(s[i]);
              //printf("%d %d\n",u,c);
              if(tr[u][c] == -1)
                   tr[u][c] = newnode();
              u = tr[u][c];
         }
         vis[string(s)] = u; //这个字符串相应的结点编号
         //printf("%d\n",u);
         val[u] ++;//达到这个结点的单词
    }
    void build(){
        queue<int>q;
        fail[root] = root;
        for(int i = 0; i < 26; i++){
            if(tr[root][i] == -1)
               tr[root][i] = root;
            else{
                fail[tr[root][i]] = root;
                q.push(tr[root][i]);
            }
        }
        while(!q.empty()){
            int now = q.front(); q.pop();
            for(int i = 0; i < 26; i++){
                if(tr[now][i] == -1)
                    tr[now][i] = tr[fail[now]][i];
                else{
                    fail[tr[now][i]] = tr[fail[now]][i];
                    q.push(tr[now][i]);
                }
            }
        }
    }
    void countt(char *s){
        int n = strlen(s);
        int u = root;
        for(int i = 0; i < n; i++){
            u = tr[u][index(s[i])];
            int temp = u;
            while(temp != root){
                if(val[temp]){           //这个结点存在单词
                    countx[temp]++;      //这个结点
                    _max = max(_max,countx[temp]);
                }
                temp = fail[temp];
            }
        }
    }
};
Trie ac;
int main(){
    int n;
    while(scanf("%d",&n) && n){
        ac.init();
        for(int i = 0; i < n; i++){
            scanf("%s",str[i]);
            ac.insert(str[i],i); //插入单词
        }
        //printf("%d\n",ac.sz);
        ac.build();
        scanf("%s",_str);
        ac.countt(_str);
        printf("%d\n",ac._max);
        for(int i = 0; i < n; i++){
            if(ac.countx[ac.vis[string(str[i])]] == ac._max)
               printf("%s\n",str[i]);
        }
    }
    return 0;
}
时间: 2024-12-16 08:40:40

【UVA】1449-Dominating Patterns(AC自己主动机)的相关文章

uva 1449 - Dominating Patterns(AC自动机)

题目练级:uva 1449 - Dominating Patterns 题目大意:有一个由小写字母组成的字符串集和一个文本T,要求找出那些字符串在文本中出现的次数最多. 解题思路:将字符串集建立AC自动机,然后传入T进行匹配,对每个匹配上的字符串多应次数加1,最后找出最大值.出现次数与最大值相同的字符串输出.注意字符集中出现相同字符的情况. #include <cstdio> #include <cstring> #include <queue> #include &l

【UVA】11468-Substring(AC自己主动机)

AC自己主动机的题,须要注意的,建立失配边的时候,假设结点1失配边连到的那个结点2,那个结点2是一个单词的结尾,那么这个结点1也须要标记成1(由于能够看成,这个结点包括了这个单词),之后在Trie树上进行行走,每次走到下一个能够走的结点. 14378527 11468 Substring Accepted C++ 0.585 2014-10-19 10:35:00 #include<cstdio> #include<cstring> #include<algorithm>

UVa 1449 Dominating Patterns

方法:AC自动机 题意比较明显,用ac 自动机.陷阱是可能会出现重复的string. code: 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 #include <string> 6 #include <vector> 7 #include <stack> 8 #include <bits

字符串算法之 AC自己主动机

近期一直在学习字符串之类的算法,感觉BF算法,尽管非常easy理解,可是easy超时,全部就想学习其它的一些字符串算法来提高一下,近期学习了一下AC自己主动机.尽管感觉有所收获,可是还是有些朦胧的感觉,在此总结一下,希望大家不吝赐教. 一.AC自己主动机的原理: Aho-Corasick automaton.该算法在1975年产生于贝尔实验室,是著名的多模匹配算法之中的一个. 一个常见的样例就是给出N个单词,在给出一段包括m个字符的文章,让你找出有多少个单词在这文章中出现过,.要搞懂AC自己主动

数据结构与算法系列----AC自己主动机

一:概念 首先简要介绍一下AC自己主动机:Aho-Corasick automation,该算法在1975年产生于贝尔实验室,是著名的多模匹配算法之中的一个.一个常见的样例就是给出n个单词,再给出一段文章(长度是m),让你找出有多少个单词在文章里出现过. 要搞懂AC自己主动机.先得有字典树Trie的基础知识(也有人说需要KMP的知识,我认为暂且不要理会这个. 可是在看这篇文章之前,Trie字典树,你是必需要先搞懂,假设你还不理解Trie,请參考http://blog.csdn.net/laoji

hdoj 2222 Keywords Search 【AC自己主动机 入门题】 【求目标串中出现了几个模式串】

Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 44687    Accepted Submission(s): 14103 Problem Description In the modern time, Search engine came into the life of everybody li

HDU - 3341 Lost&amp;#39;s revenge(AC自己主动机+DP)

Description Lost and AekdyCoin are friends. They always play "number game"(A boring game based on number theory) together. We all know that AekdyCoin is the man called "nuclear weapon of FZU,descendant of Jingrun", because of his talen

HDU 2222 Keywords Search(AC自己主动机模板题)

题意:给出一个字符串和若干个模板,求出在文本串中出现的模板个数. 思路:由于有可能有反复的模板,trie树权值记录每一个模板出现的次数就可以. #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #include<map&

ZOJ - 3228 Searching the String (AC自己主动机)

Description Little jay really hates to deal with string. But moondy likes it very much, and she's so mischievous that she often gives jay some dull problems related to string. And one day, moondy gave jay another problem, poor jay finally broke out a