Cod sursa(job #1232103)

Utilizator Andrei1998Andrei Constantinescu Andrei1998 Data 22 septembrie 2014 00:19:18
Problema Aho-Corasick Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 3 kb
#include <fstream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <string>

using namespace std;

struct state{
    int word;

    bool solved;
    int fail;
    int father;
    char letter;

    int transitions[26];

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

int frecv[105];

class automaton{
public:
    vector<state> states;


    inline int new_automaton_state(int father=0,char letter=0){
        states.push_back(state(father,letter));

        return (states.size()-1);
    }

public:
    automaton(){
        new_automaton_state();
    }

    inline void add_word(const string &s,int index){
        //cout<<endl;
        //cout<<"add "<<s<<' '<<index<<endl;

        int k=0;
        for(int i=0;i<s.size();i++){
            //cout<<"s[i] = "<<s[i]<<endl;

            if(!states[k].transitions[s[i]-'a']){
                int aux=new_automaton_state(k,s[i]-'a');
                states[k].transitions[s[i]-'a']=aux;
            }

            k=states[k].transitions[s[i]-'a'];
            //cout<<"k devine "<<k<<endl;
        }


        states[k].word=index;
    }

    inline void build_fails(int nod){
        if(states[nod].father){
            int k=states[states[nod].father].fail;

            while(k && !states[k].transitions[states[nod].letter]){
                if(!states[k].solved)
                    build_fails(k);
                k=states[k].fail;
            }

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

            states[nod].fail=k;
            //cout<<"states["<<nod<<"].fail = "<<k<<endl;
        }

        states[nod].solved=true;

        for(int i=0;i<26;i++)
            if(states[nod].transitions[i] && !states[states[nod].transitions[i]].solved)
                build_fails(states[nod].transitions[i]);
    }

    inline void run_automaton(const string &s){
        int k=0;

        int p;
        for(int i=0;i<s.size();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){
                if(states[p].word)
                    frecv[states[p].word]++;
                p=states[p].fail;
            }
        }
    }
};

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

    ios_base::sync_with_stdio(false);
    automaton x;

    string sir;
    cin>>sir;

    string curent;

    int n=0;
    cin>>n;

    for(int i=1;i<=n;i++){
        cin>>curent;

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

    x.run_automaton(sir);

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

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