Cod sursa(job #2589661)

Utilizator catalintermureTermure Catalin catalintermure Data 26 martie 2020 18:03:55
Problema Aho-Corasick Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.18 kb
#include <fstream>
#include <vector>
#include <cstring>

using namespace std;

ifstream inf("ahocorasick.in");
ofstream outf("ahocorasick.out");

const int SIGMA = 26;
const int LENCUV = 10000;
const int LENMAX = 1000000;
const int NMAX = 100;

struct ac {
    ac *fail;
    ac *f[SIGMA];
    int data;
    vector<int> ind;
    
    ac() {
        data = 0;
        fail = 0;
        memset(f, 0, sizeof(f));
    }
};

char s[LENMAX + 1];
char cuv[LENCUV + 1];

void insert(ac *t, char *s, int i) {
    while(*s) {
        if(t->f[*s - 'a'] == 0) {
            t->f[*s - 'a'] = new ac;
        }
        t = t->f[*s - 'a'];
        s++;
    }
    t->ind.push_back(i);
}

ac *q[LENCUV * LENCUV + 1];
int qlen;

void BFSCreateFails(ac *t) {
    ac *p;
    ac *tmpfail;
    q[0] = t;
    qlen = 1;
    t->fail = t;
    for(int i = 0; i < qlen; i++) {
        p = q[i];
        for(int c = 0; c < SIGMA; c++) {
            if(p->f[c] != 0) {
                tmpfail = p->fail;
                while(tmpfail->f[c] == 0 && tmpfail != t) {
                    tmpfail = tmpfail->fail;
                }
                if(tmpfail->f[c] != 0 && tmpfail != p) {
                    tmpfail = tmpfail->f[c];
                }
                p->f[c]->fail = tmpfail;
                q[qlen++] = p->f[c];
            }
        }
    }
    t->fail = 0;
}

int rez[NMAX];

void calc() {
    for(int i = qlen - 1; i >= 0; i--) {
        if(q[i]->fail != 0) {
            q[i]->fail->data += q[i]->data;
        }
        for(const int x : q[i]->ind) {
            rez[x] = q[i]->data;
        }
    }
}

int main() {
    ac *t = new ac;
    int n;
    inf >> s >> n;
    for(int i = 0; i < n; i++) {
        inf >> cuv;
        insert(t, cuv, i);
    }
    BFSCreateFails(t);
    int slen = strlen(s);
    ac *p = t;
    for(int i = 0; i < slen; i++) {
        int c = s[i] - 'a';
        while(p->f[c] == 0 && p != t) {
            p = p->fail;
        }
        if(p->f[c] != 0) {
            p = p->f[c];
        }
        p->data++;
    }
    calc();
    for(int i = 0; i < n; i++) {
        outf << rez[i] << '\n';
    }
    return 0;
}