Cod sursa(job #1249512)

Utilizator prisonbreakMichael Scofield prisonbreak Data 27 octombrie 2014 03:26:04
Problema Trie Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.6 kb
#include <cstdio>
#include <fstream>
#include <iostream>
#include <vector>
#include <cstring>

const int SIGMA = 26;
using namespace std;


class Node {
  Node* next[SIGMA];
  int finished;
  int how_many;
  void construct_next(int where) {
    next[where] = new Node();
  }
  int convert_to_int(char x) {
    return x - 'a';
  }

public:
  Node() {
    memset(next, 0, sizeof(next));
    finished = how_many = 0;
  }

  bool is_next(char y) {
    int x = convert_to_int(y);
    return next[x] != 0;
  }
  void setter(char y) {
    int x = convert_to_int(y);
    next[x] = 0;
  }
  Node* get_next(char y) {
    int x = convert_to_int(y);
    if (next[x] == 0) {
      this -> construct_next(x);
    }
    return next[x];
  }
  void add_final(int to_add) {
    finished += to_add;
  }
  int get_final() {
    return finished;
  }
  void add_passed(int to_add) {
    how_many += to_add;
  }
  int get_passed(){
    return how_many;
  }
};

class Trie {
  Node *root;
  string del_solve;

  int convert_to_int(char x) {
    return x - 'a';
  }
  void rec_delete(Node* cur_node, size_t idx) {
    cur_node->add_passed(-1);
    if (idx == del_solve.size()) {
      cur_node->add_final(-1);
    } else {
      Node *t = cur_node->get_next(del_solve[idx]);
      rec_delete(t, idx + 1);
      if (t->get_passed() == 0) {
        delete t;
        cur_node->setter(del_solve[idx]);
      }
    }
  }
  public:
  Trie() {
    root = new Node();
  }
  void insert_word(string s) {
    Node *tmp = root;
    for (size_t i = 0; i < s.size(); ++i) {
      tmp = tmp->get_next(s[i]);
      tmp->add_passed(+1);
    }
    tmp->add_final(1);
  }
  void delete_word(string s) {
    del_solve = s;
    rec_delete(root, 0);
  }
  int count_apparitions(string s) {
    Node *tmp = root;
    for (size_t i = 0; i < s.size(); ++i) {
      if (tmp->is_next(s[i])) {
        tmp = tmp->get_next(s[i]);
      } else {
        return 0;
      }
    }
    return tmp -> get_final();
  }
  int find_lcp(string s) {
    Node *tmp = root;
    int cur_sol = 0;
    for (size_t i = 0; i < s.size(); ++i) {
      if (tmp->is_next(s[i])) {
        tmp = tmp->get_next(s[i]);
        cur_sol += 1;
      } else {
        break;
      }
    }
    return cur_sol;
  }
};
int main() {
  ifstream cin("trie.in");
  ofstream cout("trie.out");

  int qtype;

  Trie T;
  while(cin >> qtype) {
    string word; cin >> word;
    if (qtype == 0) {
      T.insert_word(word);
    } else if (qtype == 1) {
      T.delete_word(word);
    } else if (qtype == 2) {
      cout << T.count_apparitions(word) << "\n";
    } else if (qtype == 3) {
      cout << T.find_lcp(word) << "\n";
    }
  }
  return 0;
}