Cod sursa(job #2577321)

Utilizator gabrielinelusGabriel-Robert Inelus gabrielinelus Data 8 martie 2020 23:40:29
Problema Trie Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.93 kb
#include <iostream>
#include <cstdio>
#include <vector>
#include <memory>

using namespace std;

template <typename Alphabet, typename Container>
class Trie{
public:
  typedef typename Container::iterator iter;

  Trie(int size): _size(size), _leaves(size), _wordsEndingHere(0), _numberLeaves(0){}

  void Insert(iter left, iter right)
  {
    if (left == right) {
      ++_wordsEndingHere;
      return;
    }
    if (!_leaves[*left]) {
      ++_numberLeaves;
      _leaves[*left] = make_unique<Trie<Alphabet, Container>>(Trie<Alphabet, Container>(_size));
    }
      
    _leaves[*left]->Insert(left + 1, right);
  }

  void Delete(iter left, iter right)
  {
    if (left == right) {
      --_wordsEndingHere;
      return;
    }

    _leaves[*left]->Delete(left + 1, right);

    if(!_leaves[*left]->_wordsEndingHere && !_leaves[*left]->_numberLeaves) {
      --_numberLeaves;
      _leaves[*left].reset(nullptr);
    }
  }

  int Count(iter left, iter right)
  {
    if (left == right)
      return _wordsEndingHere;
    if(!_leaves[*left])
      return 0;
    return _leaves[*left]->Count(left + 1, right);
  }

  int Prefix(iter left, iter right)
  {
    if (left == right || !_leaves[*left])
      return 0;
    return 1 + _leaves[*left]->Prefix(left + 1, right);
  }
  
private:
  vector<unique_ptr<Trie>> _leaves;
  int _size;
  int _wordsEndingHere;
  int _numberLeaves;
};

int main()
{
  freopen("trie.in", "r", stdin);
  freopen("trie.out", "w", stdout);

  auto trie = make_unique<Trie<int, vector<int>>>(Trie<int, vector<int>>(26));
  int op;
  string s;
  while(cin >> op && cin >> s) {
    vector<int> v;
    for (int i = 0; i < s.size(); ++i)
      v.emplace_back(s[i]-'a');
    if (op == 0)
      trie->Insert(v.begin(), v.end());
    else if (op == 1)
      trie->Delete(v.begin(), v.end());
    else if (op == 2)
      cout << trie->Count(v.begin(), v.end()) << "\n";
    else
      cout << trie->Prefix(v.begin(), v.end()) << "\n";
  }
  return 0;
}