Cod sursa(job #1424331)

Utilizator george_stelianChichirim George george_stelian Data 23 aprilie 2015 23:43:04
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.91 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;

class aho_corasick
{
    public:
        void add_word(string s)
        {
            wordcount++;
            int nod=rad,lim=s.length();
            for(int i=0;i<lim;i++)
            {
                if(v[nod].delta[cod(s[i])]==nil)
                {
                    int a=newnode();
                    v[nod].delta[cod(s[i])]=a;
                }
                nod=v[nod].delta[cod(s[i])];
            }
            v[nod].indcuv.push_back(wordcount-1);
        }

        void compute_delta_pi()
        {
            v[rad].pi=rad;
            q.push_back(rad);
            for(int i=0;i<q.size();i++)
            {
                int nod=q[i];
                for(int j=0;j<sigma;j++)
                {
                    int k=v[nod].pi;
                    while(k!=rad && v[k].delta[j]==nil) k=v[k].pi;
                    if(v[k].delta[j]!=nil && k!=nod) k=v[k].delta[j];
                    if(v[nod].delta[j]!=nil)
                    {
                        v[v[nod].delta[j]].pi=k;
                        q.push_back(v[nod].delta[j]);
                    }
                    else v[nod].delta[j]=k;
                }
            }
            reverse(q.begin(),q.end());
        }

        vector<int> getfreq(string s)
        {
            vector<int> freq=vector<int>(wordcount,0);
            int lim=s.length(),nod=rad;
            for(int i=0;i<lim;i++)
            {
                nod=v[nod].delta[cod(s[i])];
                v[nod].nr++;
            }
            for(vector<int>::iterator it=q.begin();it!=q.end();it++)
                if(*it!=rad) v[v[*it].pi].nr+=v[*it].nr;
            for(int i=0;i<v.size();i++)
                if(i!=rad) for(vector<int>::iterator it=v[i].indcuv.begin();it!=v[i].indcuv.end();it++) freq[*it]+=v[i].nr;
            return freq;
        }

    private:
        static const int nil=-1,sigma=26;
        struct node
        {
            int nr,pi;
            vector<int> indcuv,delta;
            node()
            {
                nr=0;
                indcuv=vector<int>();
                delta=vector<int>(sigma,nil);
            }
        };
        vector<node> v=vector<node>(1,node());
        vector<int> q;
        int wordcount=0,rad=0;

        int newnode()
        {
            v.push_back(node());
            return v.size()-1;
        }
        int cod(char c)
        {
            return c-'a';
        }
};

int main()
{
    ifstream f("ahocorasick.in");
    ofstream g("ahocorasick.out");
    int n;
    string s,s1;
    aho_corasick v;
    f>>s>>n;
    for(int i=1;i<=n;i++)
    {
        f>>s1;
        v.add_word(s1);
    }
    v.compute_delta_pi();
    vector<int> freq=v.getfreq(s);
    for(int i=0;i<n;i++) g<<freq[i]<<'\n';
    return 0;
}