Cod sursa(job #3040866)

Utilizator AleXutzZuDavid Alex Robert AleXutzZu Data 30 martie 2023 15:35:22
Problema Trie Scor 5
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.87 kb
#include <iostream>
#include <fstream>
#include <vector>

struct Trie {
private:
    struct Node {
        int words = 0;
        int children_size = 0;
        std::vector<Node *> children = std::vector<Node *>(26, std::nullptr_t());
    };

    Node *root = nullptr;

    void insert(const std::string &str, Node *&node, int ptr = 0) {
        if (node == nullptr) node = new Node;

        if (ptr == str.size()) {
            node->words++;
            return;
        }

        if (node->children[str[ptr] - 'a'] == nullptr) {
            node->children_size++;
        }

        insert(str, node->children[str[ptr] - 'a'], ptr + 1);
    }

    void remove(const std::string &str, Node *&node, int ptr = 0) {
        if (ptr == str.size() - 1) {
            node->children[str[ptr] - 'a']->words--;
            if (node->children[str[ptr] - 'a']->words == 0 && node->children[str[ptr] - 'a']->children_size == 0) {
                delete node->children[str[ptr] - 'a'];
                node->children[str[ptr] - 'a'] = nullptr;
            }
            return;
        }

        remove(str, node->children[str[ptr] - 'a'], ptr + 1);
        int remaining_children = 0;
        for (int i = 0; i < 26; ++i) {
            if (node->children[str[ptr] - 'a']->children[i] != nullptr) remaining_children++;
        }
        node->children[str[ptr] - 'a']->children_size = remaining_children;

        if (remaining_children == 0) {
            delete node->children[str[ptr] - 'a'];
            node->children[str[ptr] - 'a'] = nullptr;
        }
    }

    int max_prefix(const std::string &str, Node *node, int len = 0, int ptr = 0) {
        if (ptr == str.size() || node == nullptr) return len - 1;

        return max_prefix(str, node->children[str[ptr] - 'a'], len + 1, ptr + 1);
    }

public:
    Trie() = default;

    void insert(const std::string &str) {
        insert(str, root);
    }

    int count(const std::string &str) {
        int ptr = 0;
        Node *node = root;
        while (ptr != str.size() && node != nullptr) {
            node = node->children[str[ptr] - 'a'];
            ptr++;
        }
        if (node == nullptr) return 0;
        return node->words;
    }

    void remove(const std::string &str) {
        remove(str, root);
    }

    int max_prefix(const std::string &str) {
        return max_prefix(str, root);
    }
};

int main() {
    std::ifstream input("trie.in");
    std::ofstream output("trie.out");

    Trie trie;
    int op;
    std::string str;
    while (input >> op >> str) {
        switch (op) {
            case 0:
                trie.insert(str);
                break;
            case 1:
                trie.remove(str);
                break;
            case 2:
                output << trie.count(str) << '\n';
                break;
            default:
                output << trie.max_prefix(str) << '\n';
                break;
        }
    }

    return 0;
}