Cod sursa(job #2300892)

Utilizator TooHappyMarchitan Teodor TooHappy Data 12 decembrie 2018 11:51:54
Problema Trie Scor 55
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.36 kb
#include <bits/stdc++.h>

using namespace std;

ifstream in("trie.in");
ofstream out("trie.out");

const int Nmax = 26;

struct TrieNode {
    TrieNode* children[Nmax];
    int appearances;
    bool endOfWord;

    TrieNode () {
        for (int i = 0; i < Nmax; ++i) {
            children[i] = NULL;
        }
        appearances = 0;
        endOfWord = false;
    }

    ~TrieNode () {
        for (int i = 0; i < Nmax; ++i) {
            delete children[i];
        }
        delete[] *children;
    }
};

class Trie {
private:
    TrieNode *root;

    bool deleteWord (TrieNode *current, string word, int idx) {
        if (idx == (int)word.size()) {
            current->appearances--;

            if (current->appearances == 0) {
                current->endOfWord = false;

                for (int i = 0; i < Nmax; ++i) {
                    if (current->children[i] != NULL) {
                        return false;
                    }
                }
                return true;
            }

            return false;
        }

        TrieNode *nextNode = current->children[word[idx] - 'a'];
        if (nextNode == NULL) {
            return false;
        }

        bool shouldDeleteCurrentNode = deleteWord(nextNode, word, idx + 1);

        if (shouldDeleteCurrentNode) {
            current->children[word[idx] - 'a'] = NULL;

            for (int i = 0; i < Nmax; ++i) {
                if (current->children[i] != NULL) {
                    return false;
                }
            }
            return true;
        }

        return false;
    }
public:
    Trie () {
        root = new TrieNode;
    }

    void insert (string word) {
        TrieNode *current = this->root;

        for (auto ch: word) {
            TrieNode *nextNode = current->children[ch - 'a'];
            if (nextNode == NULL) {
                nextNode = new TrieNode;
                current->children[ch - 'a'] = nextNode;
            }

            current = nextNode;
        }
        
        current->appearances++;
        current->endOfWord = true;
    }

    void deleteWord (string word) {
        deleteWord(this->root, word, 0);
    }

    int getAppearances (string word) {
        TrieNode *current = this->root;

        for (auto ch: word) {
            TrieNode *nextNode = current->children[ch - 'a'];

            if (nextNode == NULL) {
                return 0;
            }

            current = nextNode;
        }

        return current->appearances;
    }

    int getLongestPrefix (string word) {
        TrieNode *current = this->root;

        int ans = 0;
        for (auto ch: word) {
            TrieNode *nextNode = current->children[ch - 'a'];

            if (nextNode == NULL) {
                return ans;
            }

            ++ans;
            current = nextNode;
        }

        return ans;
    }

    ~Trie () {
        delete root;
    }
};

int main() {
    ios::sync_with_stdio(false); in.tie(0); out.tie(0);

    Trie *myTrie = new Trie;

    int op;
    string word;
    while (in >> op >> word) {
        if (op == 0) {
            myTrie->insert(word);
        }
        if (op == 1) {
            myTrie->deleteWord(word);
        }
        if (op == 2) {
            out << myTrie->getAppearances(word) << "\n";
        }
        if (op == 3) {
            out << myTrie->getLongestPrefix(word) << "\n";
        }
    }

    in.close(); out.close();

    return 0;
}