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

来源:互联网 发布:太平洋电脑软件下载 编辑:程序博客网 时间:2024/05/01 01:08

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

143608411449Dominating PatternsAcceptedC++0.1462014-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;}

0 0
原创粉丝点击