Cod sursa(job #1825505)

Utilizator OwlreeRobert Badea Owlree Data 9 decembrie 2016 11:51:55
Problema Trie Scor 5
Compilator cpp Status done
Runda Arhiva educationala Marime 3.84 kb
#include <fstream>
#include <vector>
#include <string>

using namespace std;

class Trie {
private:

    class TrieNode {
    private:
        int m_Count;
        int m_ChildrenCount;
        char m_Character;
        vector <TrieNode*> m_Children;
    public:
        TrieNode(char c) {
            m_Count = 0;
            m_ChildrenCount = 0;
            m_Character = c;
            m_Children.resize(30, nullptr);
        }
        TrieNode* getNodeAt(int i) {
            return m_Children.at(i);
        }
        void addChild(int pos, char c) {
            m_Children.at(pos) = new TrieNode(c);
            m_ChildrenCount += 1;
        }
        void removeChild(int pos) {
            delete m_Children.at(pos);
            m_Children.at(pos) = nullptr;
            m_ChildrenCount -= 1;
        }
        void increment() {
            m_Count += 1;
        }
        void decrement() {
            m_Count -= 1;
        }
        int getCount() {
            return m_Count;
        }
        int getChildrenCount() {
            return m_ChildrenCount;
        }
        char getChar() {
            return m_Character;
        }
    };

    TrieNode* root = nullptr;

public:
    void addWord(string word) {

        if (root == nullptr) {
            root = new TrieNode('0');
        }

        TrieNode* here = root;

        for (int i = 0; i < (int)word.size(); ++i) {

            char c = word.at(i);
            int pos = (int)c - 97;

            TrieNode* child = here->getNodeAt(pos);

            if (child == nullptr) {
                here->addChild(pos, c);
            }

            here = here->getNodeAt(pos);

        }

        here->increment();

    }

    void removeWord(string word) {

        TrieNode* here = root;

        vector <TrieNode*> trace;

        trace.push_back(root);

        for (int i = 0; i < (int)word.size(); ++i) {

            char c = word.at(i);
            int pos = (int)c - 97;
            here = here->getNodeAt(pos);
            trace.push_back(here);

        }

        here->decrement();

        for (int i = (int)trace.size() - 1; i > 0; --i) {
            if (trace.at(i)->getCount() == 0 && trace.at(i)->getChildrenCount() == 0) {
                int pos = (int)trace.at(i)->getChar() - 97;
                trace.at(i - 1)->removeChild(pos);
            }
        }

    }

    int count(string word) {

        TrieNode* here = root;

        for (int i = 0; i < (int)word.size(); ++i) {

            char c = word.at(i);
            int pos = (int)c - 97;
            here = here->getNodeAt(pos);

            if (here == nullptr) return 0;

        }

        return here->getCount();
    }
    int getPrefixLength(string word) {

        TrieNode* here = root;
        int res = 0;
        for (int i = 0; i < (int)word.size(); ++i) {

            char c = word.at(i);
            int pos = (int)c - 97;
            here = here->getNodeAt(pos);

            if (here == nullptr) {
                res = i;
                break;
            }

        }

        return res;

    }

};

int main() {

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

    Trie* T = new Trie();

    while (true) {
        int op = -1; in >> op;

        if (0 <= op && op < 4) {
            string word; in >> word;
            switch (op) {
            case 0:
                T->addWord(word);
                break;
            case 1:
                T->removeWord(word);
                break;
            case 2:
                out << T->count(word) << "\n";
                break;
            case 3:
                out << T->getPrefixLength(word) << "\n";
                break;
            }
        } else {
            break;
        }


    }

    return 0;
}