Cod sursa(job #1526706)

Utilizator paul-gPaul Grigoras paul-g Data 17 noiembrie 2015 02:55:55
Problema Trie Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.79 kb
// (a..z) --> Nodes
// Terminating character
// ab aba
// a -> b (null)
// a -> b (1) -> a (1)
//
// a -> b -> a (null)

#include <string>
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int alpha = 'z' - 'a' + 1;

struct Node {
  vector<Node*> cs;
  vector<int>   count;

  Node() {
    cs = vector<Node*>(alpha, NULL);
    count = vector<int>(alpha, 0);
  }

  Node* get_node(char c) {
    return cs[c - 'a'];
  }

  void set_node(char c, Node *n) {
    cs[c - 'a'] = n;
  }

  int get_count(char c) {
    return count[c - 'a'];
  }

  void inc_count(char c) {
    count[c - 'a']++;
  }

  int dec_count(char c) {
    return --count[c - 'a'];
  }

  int children_count() {
    int count = 0;
    for (int i = 0; i < cs.size(); i++)
      count += cs[i] == NULL ? 0 : 1;
    return count;
  }

};

class Trie {

  public:
    Node* root;
    Trie() {
      root = new Node();
    }

    void insert(const string& w) {
      Node* crt = root;
      int i = 0;
      for (; i < w.size(); i++) {
        char c = w[i];
        if (crt->get_node(c) == NULL)
          crt->set_node(c, new Node());
        crt = crt->get_node(c);
      }
      crt->inc_count(w[i]);
    }


    void del(const string& w) {
      del_rec(w, root, 0);
    }

    string lcp(const string& w) {
      Node *crt = root;
      int i = 0;
      string l;
      for (; i < w.size(); i++) {
        char c = w[i];
        if (crt->get_node(c) != NULL) {
          crt = crt->get_node(c);
          l += c;
          //std::cout << "Update best" << std::endl;
        }
      }
      return l;
    }

    int count(const string& w) {
      Node* crt = root;
      int i = 0;
      for (; i < w.size(); i++) {
        crt = crt->get_node(w[i]);
        if (crt == NULL)
          return 0;
      }
      return crt->get_count(w[i]);
    }

    Node* del_rec(const string& w, Node* n, int pos) {
      if (n == NULL)
        return NULL;
      char c = w[pos];
      //std::cout << "del_rec " << c << " " << n->get_count(c) << std::endl;
      if (pos == w.size()) {
        if (n->dec_count(c) > 0)
          return n;
        n->set_node(c, NULL);
      } else
        n->set_node(c, del_rec(w, n->get_node(c), pos + 1));
      //std::cout << c << " " << n->children_count() << std::endl;
      if (n->children_count() == 0) {
        //std::cout << "Deleting node" << std::endl;
        delete n;
        return NULL;
      }
      return n;
    }

};


int main () {
  ifstream f("trie.in");
  ofstream g("trie.out");
  int a;
  string s;
  Trie t;
  while (f >> a >> s) {
    switch (a) {
      case 0:
        t.insert(s);
        break;
      case 1:
        t.del(s);
        break;
      case 2:
        g << t.count(s) << endl;
        break;
      case 3:
        g << t.lcp(s).size() << endl;
        break;
    }
  }
}