Cod sursa(job #1526792)

Utilizator paul-gPaul Grigoras paul-g Data 17 noiembrie 2015 12:07:35
Problema Trie Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 2.58 kb
#include <string>
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>

using namespace std;

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

struct Node {
  int count;
  Node* cs[alpha];

  Node() {
    count = 0;
    memset(cs, 0, sizeof(Node*) * alpha);
  }

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

  inline void set_node(char c, Node *n) {
    Node* old = cs[c - 'a'];
    if (old == NULL && n != NULL)
      n_children++;
    else if (old != NULL && n == NULL)
      n_children--;
    cs[c - 'a'] = n;
  }

  inline int children() {
    return n_children;
  }

  private:
  int n_children;
};

class Trie {

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

    Node* insert2(const string& w, Node *crt, int pos) {
      char c = w[pos];
      Node* nxt = crt->get_node(c);
      if (nxt == NULL) {
        nxt = new Node();
        crt->set_node(c, nxt);
      }
      if (w.size() - 1 == pos) {
        nxt->count++;
        return crt;
      }
      crt->set_node(c, insert2(w, nxt, pos + 1));
      return crt;
    }

    void insert(const string& w) {
      insert2(w, root, 0);
    }

    string lcp2(const string& w, Node * n, int pos) {
      if (pos == w.size())
        return "";
      Node* nxt = n->get_node(w[pos]);
      if (nxt == NULL)
        return "";
      return w[pos] + lcp2(w, nxt, pos + 1);
    }

    string lcp(const string& w) {
      return lcp2(w, root, 0);
    }

    int count2(const string& w, Node* crt, int pos) {
      Node* nxt = crt->get_node(w[pos]);
      if (nxt == NULL)
        return 0;
      if (pos == w.size() - 1)
        return nxt->count;
      return count2(w, nxt, pos + 1);
    }

    int count(const string& w) {
      return count2(w, root, 0);
    }

    void del(const string& w) {
      if (del_rec(w, root, 0) == NULL)
        root = new Node();
    }

    Node* del_rec(const string& w, Node* n, int pos) {
      if (pos == w.size()) {
        n->count--;
      } else {
        char c = w[pos];
        n->set_node(c, del_rec(w, n->get_node(c), pos + 1));
      }
      if (n->children() == 0 && n->count <= 0) {
        delete n;
        return NULL;
      }
      return n;
    }

};


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