Cod sursa(job #1232377)

Utilizator Andrei1998Andrei Constantinescu Andrei1998 Data 22 septembrie 2014 19:38:48
Problema Aho-Corasick Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.02 kb
#include <fstream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>

using namespace std;

struct state{
    vector<int> word;

    int fail;
    int father;
    char letter;

    int transitions[26];

    state(int father=0,char letter=0): fail(0),  father(father), letter(letter) {
        memset(transitions, 0, sizeof(transitions));
    }
};

int frecv[105];

class automaton{
public:
    //vector<state> states;
    state states[1000005];
    int cate;

    inline int new_automaton_state(int father=0,char letter=0){
        states[++cate]=state(father,letter);

        return (cate);
    }

public:
    automaton(){
        cate=-1;
        new_automaton_state();
    }

    inline void add_word(const char *s,int index,int marime){
        int k=0;
        for(int i=0;i<marime;i++){
            if(!states[k].transitions[s[i]-'a'])
                states[k].transitions[s[i]-'a']=new_automaton_state(k,s[i]-'a');

            k=states[k].transitions[s[i]-'a'];
        }

        states[k].word.push_back(index);
    }

    inline void build_fails(){
        queue<int> coada;
        coada.push(0);

        int k;
        int y;
        while(!coada.empty()){
            y=coada.front();
            coada.pop();

            if(states[y].father){
                k=states[states[y].father].fail;

                while(k && !states[k].transitions[states[y].letter])
                    k=states[k].fail;

                if(states[k].transitions[states[y].letter])
                    k=states[k].transitions[states[y].letter];

                states[y].fail=k;
            }

            for(int i=0;i<26;i++)
                if(states[y].transitions[i])
                    coada.push(states[y].transitions[i]);
        }
    }

    inline void run_automaton(const char *s,int marime){
        int k=0;

        int p;
        vector<int>::iterator it;
        for(int i=0;i<marime;i++){
            while(k && !states[k].transitions[s[i]-'a'])
                k=states[k].fail;

            if(states[k].transitions[s[i]-'a'])
                k=states[k].transitions[s[i]-'a'];

            p=k;

            while(p){
                for(it=states[p].word.begin();it!=states[p].word.end();it++)
                    frecv[*it]++;
                p=states[p].fail;
            }

        }
    }
};

char sir[1000005];

    automaton x;
int main()
{
    ifstream cin("ahocorasick.in");
    ofstream cout("ahocorasick.out");

    ios_base::sync_with_stdio(false);


    int marime;
    cin.get(sir,1000005);
    marime=strlen(sir);

    char curent[10005];
    int lung;

    int n=0;
    cin>>n;

    for(int i=1;i<=n;i++){
        cin.get();
        cin.get(curent,10005);
        lung=strlen(curent);

        x.add_word(curent,i,lung);
    }
    x.build_fails();

    x.run_automaton(sir,marime);

    for(int i=1;i<=n;i++)
        cout<<frecv[i]<<'\n';

    cin.close();
    cout.close();
    return 0;
}