Cod sursa(job #2921632)

Utilizator tzancauraganuTzanca Uraganu tzancauraganu Data 1 septembrie 2022 00:04:36
Problema Trie Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.84 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <cassert>
#include <set>
#include <unordered_map>
#include <memory>

using namespace std;

struct Node {
    int count = 0;
    unordered_map<char, std::unique_ptr<Node> > edges;
};

void add(Node& n, const string& s, int p) {
    if (p >= s.size()) {
        ++n.count;
        return;
    }
    if (n.edges.find(s[p]) == n.edges.end())
        n.edges[s[p]] = std::unique_ptr<Node>(new Node());
    add(*n.edges[s[p]], s, p + 1);
}

bool remove(Node& n, const string& s, int p) {
    if (p >= s.size()) {
        assert(n.count > 0);
        --n.count;
        return n.count <= 0 && n.edges.empty();
    }

    auto it = n.edges.find(s[p]);
    assert(it != n.edges.end());
    bool shouldRemove = remove(*it->second, s, p + 1);

    if (shouldRemove)
        n.edges.erase(it);
    
    return n.count <= 0 && n.edges.empty();
}

int count(const Node& root, const string& s) {
    Node const* n = &root;

    for (int p = 0; p < s.size(); p++) {
        auto it = n->edges.find(s[p]);
        if (it == n->edges.end())
            return 0;
        n = it->second.get();
    }

    return n->count;
}

int maxLen(const Node& root, const string& s) {
    Node const* n = &root;

    for (int p = 0; p < s.size(); p++) {
        auto it = n->edges.find(s[p]);
        if (it == n->edges.end())
            return p;
        n = it->second.get();
    }

    return s.size();
}

int main() {
    ifstream f("trie.in");
    ofstream g("trie.out");

    Node root;
    int op;
    string s;

    while (f >> op >> s) {
        
        if (op == 0)
            add(root, s, 0);
        else if (op == 1)
            remove(root, s, 0);
        else if (op == 2)
            g << count(root, s) << '\n';
        else if (op == 3)
            g << maxLen(root, s) << '\n';
    }

    f.close();
    g.close();
    return 0;
}