Cod sursa(job #1787609)

Utilizator cella.florescuCella Florescu cella.florescu Data 24 octombrie 2016 20:37:24
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.08 kb
#include <bits/stdc++.h>

using namespace std;

const int MAXLIT = 26;
const int MAXN = 100;
const int MAXLW = 10000;
const int MAXL = 1000000;

struct AhoNode {
  int ap;
  vector <int> words;
  AhoNode *son[MAXLIT], *fail;
  AhoNode () {
    fail = NULL; ap = 0;
    memset(son, 0, sizeof(son));
  }
} *root = new AhoNode();

void myinsert(AhoNode *node, char *s, int ind) {
  if (isalpha(*s) == 0) {
    node->words.push_back(ind);
    return;
  }
  if (node->son[*s - 'a'] == NULL)
    node->son[*s - 'a'] = new AhoNode();
  myinsert(node->son[*s - 'a'], s + 1, ind);
}

vector <AhoNode *> v;

void bfs() {
  v.push_back(root);
  AhoNode *node, *f_node;
  root->fail = root;
  for (int i = 0; i < v.size(); ++i) {
    node = v[i];
    for (int j = 0; j < MAXLIT; ++j)
      if (node->son[j] != NULL) {
        f_node = node->fail;
        while(f_node != root && f_node->son[j] == NULL)
          f_node = f_node->fail;
        if (f_node->son[j] != NULL && f_node->son[j] != node->son[j])
          f_node = f_node->son[j];
        node->son[j]->fail = f_node;
        v.push_back(node->son[j]);
      }
  }
  root->fail = NULL;
}

int ans[MAXN + 1];

void rev_bfs() {
  AhoNode *node;
  for (int i = v.size() - 1; i >= 0; --i) {
    node = v[i];
    if (node->fail != NULL)
      node->fail->ap += node->ap;
    for (int j = 0; j < node->words.size(); ++j)
      ans[node->words[j]] = node->ap;
  }
}

char text[MAXL + 1], word[MAXLW + 1];

int main()
{
    FILE *fin, *fout;
    int n, x;
    AhoNode *node;
    fin = fopen("ahocorasick.in", "r");
    fscanf(fin, "%s %d ", text, &n);
    for (int i = 1; i <= n; ++i) {
      fscanf(fin, "%s ", word);
      myinsert(root, word, i);
    }
    fclose(fin);
    node = root;
    bfs();
    for (int i = 0; isalpha(text[i]); ++i) {
      x = text[i] - 'a';
      while (node != root && node->son[x] == NULL)
        node = node->fail;
      if (node->son[x] != NULL)
        node = node->son[x];
      node->ap++;
    }
    rev_bfs();
    fout = fopen("ahocorasick.out", "w");
    for (int i = 1; i <= n; ++i)
      fprintf(fout, "%d\n", ans[i]);
    fclose(fout);
    return 0;
}