Cod sursa(job #2972386)

Utilizator gabrielinelusGabriel-Robert Inelus gabrielinelus Data 29 ianuarie 2023 13:40:06
Problema Trie Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.8 kb
#include <cstdio>
#include <memory>
#include <vector>
#include <unordered_map>
#include <string>
#include <iterator>

using namespace std;


template <typename T>
class Trie{
private:
  unordered_map<T, unique_ptr<Trie<T>>> sons;
  int wordsEndHere;
  int sonsCount;

  void Insert(typename vector<T>::iterator begin, typename vector<T>::iterator end);
  void Remove(typename vector<T>::iterator begin, typename vector<T>::iterator end);
  int Count(typename vector<T>::iterator begin, typename vector<T>::iterator end);
  int LongestPrefix(typename vector<T>::iterator begin, typename vector<T>::iterator end);

public:
  void Insert(vector<T> word) {
    Insert(word.begin(), word.end());
  }
  void Remove(vector<T> word) {
    if (Count(word) > 0)
      Remove(word.begin(), word.end());
  }
  int Count(vector<T> word) {
    return Count(word.begin(), word.end());
  }
  int LongestPrefix(vector<T> word) {
    return LongestPrefix(word.begin(), word.end());
  }
};

template <typename T>
void Trie<T>::Insert(typename vector<T>::iterator begin, typename vector<T>::iterator end) {
  if (begin == end) {
    ++wordsEndHere;
    return;
  }
  if (sons.count(*begin) == 0) {
    ++sonsCount;
    sons[*begin] = make_unique<Trie<T>>();
  }
  sons[*begin]->Insert(begin+1, end);
}

template <typename T>
void Trie<T>::Remove(typename vector<T>::iterator begin, typename vector<T>::iterator end) {
  if (begin == end) {
    wordsEndHere--;
    return;
  }
  sons[*begin]->Remove(begin + 1, end);
  if (sons[*begin]->sonsCount == 0 && sons[*begin]->wordsEndHere == 0) {
    //sons[*begin].reset();
    sons.erase(*begin); 
    --sonsCount;
  }
}

template <typename T>
int Trie<T>::Count(typename vector<T>::iterator begin, typename vector<T>::iterator end) {
  if (begin == end) {
    return wordsEndHere;
  }
  if (sons.count(*begin) == 0)
    return 0;
  return sons[*begin]->Count(begin+1, end);
}

template <typename T>
int Trie<T>::LongestPrefix(typename vector<T>::iterator begin, typename vector<T>::iterator end) {
  if (begin == end || sons.count(*begin) == 0) {
    return 0;
  }
  return 1 + sons[*begin]->LongestPrefix(begin+1, end);
}

class Solver{
private:
public:
  Solver() {
    freopen("trie.in", "r", stdin);
    freopen("trie.out", "w", stdout);
  }
  ~Solver() {
    fclose(stdin);
    fclose(stdout);
  }
  void executeQueries() {
    int op;
    char s[30];
    unique_ptr<Trie<char>> trie = make_unique<Trie<char>>();
    while(scanf("%d %s", &op, s) == 2) {
      string aux = s;
      vector<char> str(aux.begin(), aux.end());
      if(op == 0)
	trie->Insert(str);
      else if (op == 1) 
	trie->Remove(str);
      else if (op == 2)
	printf("%d\n", trie->Count(str));
      else printf ("%d\n", trie->LongestPrefix(str));
    }
  }
};


  
int main()
{
  unique_ptr<Solver> s = make_unique<Solver>();
  s->executeQueries();
  return 0;
}