Cod sursa(job #1560158)

Utilizator hrazvanHarsan Razvan hrazvan Data 1 ianuarie 2016 20:51:03
Problema Aho-Corasick Scor 100
Compilator c Status done
Runda Arhiva educationala Marime 2.04 kb
#include <stdio.h>
#include <stdlib.h>
#define MAXL 1000000
#define MAXC 10000
#define MAXN 100
#define SIG 26
typedef struct nodul{
  struct nodul *fii[SIG];
  struct nodul *fail;
  int nr;
}nod;
char s[MAXL + 2], cuv[MAXC + 2];
nod root, nul;
nod *last[MAXN];
nod *bfs[MAXN * MAXC];
int dr;

nod* add(nod *p, char *s, int k, int d){
  if(k == d){
    return p;
  }
  s[k] -= 'a';
  if(p->fii[s[k]] == &nul){
    p->fii[s[k]] = (nod*) malloc(sizeof(nod));
    *(p->fii[s[k]]) = nul;
  }
  return add(p->fii[s[k]], s, k + 1, d);
}

inline void brtfs(){
  int st, i;
  nod *x;
  nod *p;
  st = 0;  dr = 0;
  for(i = 0; i < SIG; i++){
    if(root.fii[i] != &nul){
      bfs[dr] = root.fii[i];
      root.fii[i]->fail = &root;
      dr++;
    }
  }
  while(st < dr){
    p = bfs[st];
    st++;
    for(i = 0; i < SIG; i++){
      if(p->fii[i] != &nul){
        bfs[dr] = p->fii[i];
        dr++;
        x = p->fail;
        while(x != &root && x->fii[i] == &nul)
          x = x->fail;
        if(x->fii[i] == &nul)
          p->fii[i]->fail = x;
        else
          p->fii[i]->fail = x->fii[i];
      }
    }
  }
}

inline void antibfs(){
  int i;
  for(i = dr - 1; i >= 0; i--){
    bfs[i]->fail->nr += bfs[i]->nr;
  }
}

int main(){
  FILE *in = fopen("ahocorasick.in", "r");
  fgets(s, MAXL + 2, in);
  int n, l, i;
  fscanf(in, "%d ", &n);
  for(i = 0; i < SIG; i++)
    root.fii[i] =  nul.fii[i] = &nul;
  root.fail = &root;
  for(i = 0; i < n; i++){
    fgets(cuv, MAXC + 2, in);
    l = 0;
    while(cuv[l] >= 'a' && cuv[l] <= 'z')
      l++;
    last[i] = add(&root, cuv, 0, l);
  }
  fclose(in);
  brtfs();
  nod *p = &root;
  char x;
  for(i = 0; s[i] >= 'a' && s[i] <= 'z'; i++){
    x = s[i] - 'a';
    while(p != &root && p->fii[x] == &nul)
      p = p->fail;
    if(p->fii[x] != &nul)
      p = p->fii[x];
    (p->nr)++;
  }
  antibfs();
  FILE *out = fopen("ahocorasick.out", "w");
  for(i = 0; i < n; i++)
    fprintf(out, "%d\n", last[i]->nr);
  fclose(out);
  return 0;
}