Cod sursa(job #2039839)

Utilizator mihai.alphamihai craciun mihai.alpha Data 14 octombrie 2017 23:41:04
Problema Aho-Corasick Scor 45
Compilator cpp Status done
Runda Arhiva educationala Marime 2.27 kb
#include <cstdio>
#include <cstring>
#include <cctype>
#include <queue>
#include <vector>

FILE *fin, *fout;

#define LGA 1000000
#define LGC 10000
#define sigma 26
#define MAXN 100

char a[LGA + 3];

struct trie  {
    trie *fii[sigma], *fail;
    int nr;
    trie () {
        nr = 0;
        memset(fii, 0, sizeof fii);
        fail = 0;
    }
};

trie *root, *ans[MAXN + 1];
trie *q[LGC * MAXN + 1];

int st, dr;

inline void Fail()  {
    trie *aux;
    for(int i = 0;i < sigma;i++)  {
        if(root -> fii[i] != 0)  {
            q[++dr] = root -> fii[i];
            root -> fii[i] -> fail = root;
        }
    }
    st = 1;
    while(st < dr)  {
        for(int i = 0;i < sigma;i++)  {
            if(q[st] -> fii[i] != 0)  {
                q[++dr] = q[st] -> fii[i];
                aux = q[st] -> fail;
                while(aux -> fii[i] == 0 && aux != root)
                    aux = aux -> fail;
                if(aux -> fii[i] != 0)  {
                    q[st] -> fii[i] -> fail = aux -> fii[i];
                }
                else
                    q[st] -> fii[i] -> fail = root;
            }
        }
        st++;
    }
}



int main()  {
    fin = fopen("ahocorasick.in", "r"), fout = fopen("ahocorasick.out", "w");
    fgets(a + 1, LGA + 2, fin);
    int m = strlen(a + 1) - 1;
    int n;
    fscanf(fin, "%d", &n);
    fgetc(fin);
    trie *aux;
    root = new trie;
    for(int i = 1;i <= n;i++)  {
        char ch = fgetc(fin);
        aux = root;
        while(isalpha(ch))  {
            if(aux -> fii[ch - 'a'] == 0)  {
                aux -> fii[ch - 'a'] = new trie;
            }
            aux = aux -> fii[ch - 'a'];
            ch = fgetc(fin);
        }
        ans[i] = aux;
    }
    Fail();
    aux = root;
    for(int i = 1;i <= m;i++)  {
        while((aux != root) && (aux -> fii[a[i] - 'a'] == 0))  {
            aux = aux -> fail;
        }
        if(aux -> fii[a[i] - 'a'] != 0)  {
            aux = aux -> fii[a[i] - 'a'];
        }
        aux -> nr++;
    }
    for(int i = dr;i > 0;i--)  {
        q[i] -> fail -> nr += q[i] -> nr;
    }
    for(int i = 1;i <= n;i++)
        fprintf(fout, "%d\n", ans[i] -> nr);
    fclose(fin), fclose(fout);
    return 0;
}