Cod sursa(job #3172400)

Utilizator AdelaCorbeanuAdela Corbeanu AdelaCorbeanu Data 20 noiembrie 2023 16:24:11
Problema Trie Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.03 kb
#include <fstream>
#include <unordered_map>
#include <iostream>

struct TrieNode {
    std::unordered_map<char, TrieNode*> children;
    int occurrences = 0;

    explicit TrieNode(int occurences = 0) : occurrences(occurences) {}
};

class Trie {
private:
    TrieNode* root = new TrieNode();

    TrieNode* get_node(const std::string& word) const {
        auto current_node = root;

        for (auto letter : word) {
            if (!current_node->children.count(letter)) return nullptr;

            current_node = current_node->children[letter];
        }

        return current_node;
    }

public:
    void insert(const std::string& word) {
        auto current_node = root;

        for (auto& letter : word) {
            if (!current_node->children.count(letter))
                current_node->children[letter] = new TrieNode();
            current_node = current_node->children[letter];
        }

        current_node->occurrences++;
    }

    int get_occurrences(const std::string& word) const {
        auto word_node = get_node(word);
        return word_node ? word_node->occurrences : 0;
    }

    int get_longest_common_prefix_length(const std::string& word) const {
        auto current_node = root;
        int common_prefix_length = 0;

        for (auto letter : word) {
            if (!current_node->children.count(letter)) return common_prefix_length;

            ++common_prefix_length;
            current_node = current_node->children[letter];
        }

        return common_prefix_length;
    }

    void remove(const std::string& word) {
        TrieNode* current_node = root;
        TrieNode* last_valid_node = nullptr;
        char last_valid_char = '\0';

        for (auto letter : word) {
            if (current_node->occurrences > 1 || current_node->children.size() > 1) {
                last_valid_node = current_node;
                last_valid_char = letter;
            }

            if (!current_node->children.count(letter)) {
                return;
            }

            current_node = current_node->children[letter];
        }

        if (current_node->occurrences > 1 || current_node->children.size() > 0) {
            current_node->occurrences--;
        }
        else {
            delete current_node;
            last_valid_node->children.erase(last_valid_char);
        }
    }
};

int main() {
    std::ifstream fin("trie.in");
    std::ofstream fout("trie.out");

    Trie trie;
    int operation;

    while (fin >> operation) {
        std::string word;
        fin >> word;

        switch (operation) {
            case 0:
                trie.insert(word);
                break;
            case 1:
                trie.remove(word);
                break;
            case 2:
                fout << trie.get_occurrences(word) << '\n';
                break;
            case 3:
                fout << trie.get_longest_common_prefix_length(word) << '\n';
                break;
        }
    }

    return 0;
}