UVALive 4670 Dominating Patterns --AC自动机第一题

题意:多个模板串,一个文本串,求出那些模板串在文本串中出现次数最多。

解法:AC自动机入门模板题。

代码:

#include <iostream>

#include <cstdio>

#include <cstring>

#include <cstdlib>

#include <cmath>

#include <algorithm>

#include <string>

#include <vector>

#include <queue>

#include <map>

#define Mod 1000000007

using namespace std;

#define N 1000007



const int MAXNODE = 20005;

const int SIZE = 26;

int cnt[MAXNODE];

struct Trie {

    int ch[MAXNODE][SIZE],val[MAXNODE],sz,fail[MAXNODE],last[MAXNODE];

    Trie() { sz = 1; memset(ch[0],0,sizeof(ch[0])); }

    int idx(char c) { return c-'a'; };

    void init() { sz = 1; memset(ch[0],0,sizeof(ch[0])); memset(cnt,0,sizeof(cnt)); }

    void print(int j) {

        if(j) {

            cnt[val[j]]++;

            print(last[j]);

        }

        return;

    }

    void Insert(char *s,int v) {

        int u = 0, n = strlen(s);

        for(int i=0;i<n;i++) {

            int c = idx(s[i]);

            if(!ch[u][c]) {

                memset(ch[sz],0,sizeof(ch[sz]));

                val[sz] = 0;

                ch[u][c] = sz++;

            }

            u = ch[u][c];

        }

        val[u] = v;

    }

    void getFail() {

        queue<int> q;

        fail[0] = 0;

        for(int c=0;c<SIZE;c++) {

            int u = ch[0][c];

            if(u) { fail[u] = 0; q.push(u); last[u] = 0; }

        }

        while(!q.empty()) {

            int r = q.front(); q.pop();

            for(int c=0;c<SIZE;c++) {

                int u = ch[r][c];

                if(!u) continue;

                q.push(u);

                int v = fail[r];

                while(v && !ch[v][c]) v = fail[v];

                fail[u] = ch[v][c];

                last[u] = val[fail[u]] ? fail[u] : last[fail[u]];

            }

        }

    }

    void query(char *T) {

        int n = strlen(T), j = 0;

        for(int i=0;i<n;i++) {

            int c = idx(T[i]);

            while(j && !ch[j][c]) j = fail[j];

            j = ch[j][c];

            if(val[j]) print(j);

            else if(last[j]) print(last[j]);

        }

    }

};

char T[N],ss[160][77];

map<string,int> mp;

Trie ac;



int main()

{

    int n,i;

    while(scanf("%d",&n)!=EOF && n)

    {

        mp.clear();

        ac.init();

        for(i=1;i<=n;i++) {

            scanf("%s",ss[i]);

            ac.Insert(ss[i],i);

            mp[string(ss[i])] = i;

        }

        ac.getFail();

        scanf("%s",T);

        ac.query(T);

        int Maxi = -1;

        for(i=1;i<=n;i++)

            Maxi = max(Maxi,cnt[i]);

        cout<<Maxi<<endl;

        for(i=1;i<=n;i++) {

            if(cnt[mp[string(ss[i])]] == Maxi)

                printf("%s\n",ss[i]);

        }

    }

    return 0;

}
View Code

 

你可能感兴趣的:(Pattern)