Cod sursa(job #2116132)

Utilizator abel.metinaru112Abel Metinaru abel.metinaru112 Data 27 ianuarie 2018 12:48:25
Problema Aho-Corasick Scor 75
Compilator cpp Status done
Runda Arhiva educationala Marime 2.71 kb
#include <iostream>
#include <vector>
#include <queue>
#include <fstream>

#define nMax 103
#define cuvMax 10003
#define txtMax 1000003

using namespace std;

ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");

int n, nr_app[nMax] = {};
int cindex;
char txt[txtMax];

vector < char > imply[nMax];

class ahtree{
public:
    char index = NULL;
    ahtree *v[26] = {};
    ahtree *failure = nullptr;
    void insert(char cuv[cuvMax]);
}*root = new ahtree;

void ahtree :: insert(char cuv[cuvMax]){
    if(!cuv[0]){
        if(index){
            imply[index].push_back(cindex);
        }
        else{
            index = cindex;
        }
        return;
    }
    int i = cuv[0] - 'a';
    if(!v[i]){
        v[i] = new ahtree;
    }
    v[i] ->insert(cuv + 1);
    return;
}



void fix_failure(){
    queue < ahtree* > Q;
    ahtree *now = root, *it;
    for(int i = 0; i < 26; i ++){
        if(root ->v[i]){
            root ->v[i] ->failure = root;
            Q.push(root ->v[i]);
        }
    }
    while(!Q.empty()){
        now = Q.front();
        Q.pop();
        if(now ->failure ->index){
            if(now ->index){
                imply[now ->index].push_back(now ->failure ->index);
            }
            else{
                now ->index = now ->failure ->index;
            }
        }
        for(int i = 0; i < 26; i ++){
            if(now ->v[i]){
                for(it = now ->failure; it; it = it ->failure){
                    if(it ->v[i]){
                        break;
                    }
                }
                if(it){
                    now ->v[i] ->failure = it ->v[i];
                }
                else{
                    now ->v[i] ->failure = root;
                }
                Q.push(now ->v[i]);
            }
        }
    }
    return;
}


void search(){
    ahtree *now = root;
    int i = 0, j;
    while(txt[i]){
        j = txt[i] - 'a';
        if(now ->v[j]){
            now = now ->v[j];
            ++ i;
            ++ nr_app[now ->index];
        }
        else{
            if(now ->failure){
                now = now ->failure;
            }
            else{
                ++ i;
            }
        }
    }
    for(int i = 1; i <= n; i ++){
        for(int j = 0; j < imply[i].size(); j ++){
            nr_app[imply[i][j]] += nr_app[i];
        }
    }
    return;
}

int main(){
    char cuv[cuvMax];
    fin>>txt>>n;
    for(cindex = 1; cindex <= n; cindex ++){
        fin>>cuv;
        root ->insert(cuv);
    }
    fix_failure();
    search();
    for(int i = 1; i <= n; i ++){
        fout<<nr_app[i]<<"\n";
    }
	return 0;
}