Cod sursa(job #1309174)

Utilizator cata00Catalin Francu cata00 Data 5 ianuarie 2015 14:53:15
Problema Trie Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.79 kb
#include <stdio.h>

#define MAX_LEN 20
#define SIGMA 26
#define MAX_CELLS 130000

typedef struct {
  int child[SIGMA], parent;
  unsigned short value;
  char numChildren;
} trie;

trie t[MAX_CELLS];     // nu vom folosi poziția 0, căci 0 semnifică NULL
int st[MAX_CELLS], ss; // stivă de celule refolosibile
int tsize = 2;         // prima poziție disponibilă

inline int alloc() {
  return ss ? st[--ss] : tsize++;
}

inline void dealloc(int pos) {
  st[ss++] = pos;
}

void insert(char *s) {
  int index = 1;
  for (; *s; s++) {
    int c = *s - 'a';
    if (!t[index].child[c]) {
      t[index].child[c] = alloc();
      t[t[index].child[c]].parent = index;
      t[index].numChildren++;
    }
    index = t[index].child[c];
  }
  t[index].value++;
}

void erase(char *s) {
  int index = 1;
  for (; *s; s++) {
    index = t[index].child[*s - 'a'];
  }
  t[index].value--;
  while (!t[index].value && !t[index].numChildren && (index != 1)) {
    s--;
    dealloc(index);
    index = t[index].parent;
    t[index].child[*s - 'a'] = 0;
    t[index].numChildren--;
  }
}

int count(char *s) {
  int index = 1;
  while (*s && t[index].child[*s - 'a']) {
    index = t[index].child[*s - 'a'];
    s++;
  }
  return *s ? 0 : t[index].value;
}

int prefixMatch(char *s) {
  int index = 1;
  char *sc = s;
  while (*s && t[index].child[*s - 'a']) {
    index = t[index].child[*s - 'a'];
    s++;
  }
  return s - sc;
}

int main(void) {
  FILE *fin = fopen("trie.in", "r");
  FILE *fout = fopen("trie.out", "w");
  int op;
  char s[MAX_LEN + 1];

  while (fscanf(fin, "%d %s", &op, s) == 2) {
    switch (op) {
      case 0: insert(s); break;
      case 1: erase(s); break;
      case 2: fprintf(fout, "%d\n", count(s)); break;
      case 3: fprintf(fout, "%d\n", prefixMatch(s)); break;
    }
  }

  fclose(fin);
  fclose(fout);
}