Cod sursa(job #2788370)

Utilizator qubitrubbitQubit Rubbit qubitrubbit Data 25 octombrie 2021 16:41:52
Problema Trie Scor 55
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.9 kb

#include <fstream>
#include <vector>
using namespace std;
ifstream fin("trie.in");
ofstream fout("trie.out");

const int ALPHA_SIZE = 26;

class Trie
{
    class Node
    {
    public:
        char c;
        Node *next[ALPHA_SIZE];
        int count;

        Node(char c)
        {
            this->c = c;
            this->count = 0;
        }
    };

private:
    void deleteBranch(vector<Node *> history)
    {
        for (int i = history.size() - 2; i >= 0; --i)
        {
            Node *curr = history[i + 1];
            Node *parent = history[i];

            if (curr->count == 0)
            {

                bool hasChildren = false;
                for (int j = 0; j < ALPHA_SIZE; ++j)
                {
                    if (curr->next[j] != nullptr)
                    {
                        hasChildren = true;
                        break;
                    }
                }
                if (!hasChildren)
                {
                    parent->next[curr->c - 'a'] = nullptr;
                    delete curr;
                }
                else
                {
                    break;
                }
            }
        }
    }

public:
    Node *root;
    Trie()
    {
        root = new Node('$');
    }

    void insertWord(char *word)
    {
        Node *prev = this->root;
        for (char *it = word; *it != '\0'; ++it)
        {
            Node *curr = prev->next[*it - 'a'];
            if (curr == nullptr)
            {
                prev->next[*it - 'a'] = new Node(*it);
                curr = prev->next[*it - 'a'];
            }
            if (*(it + 1) == '\0')
            {
                curr->count++;
            }
            prev = curr;
        }
    }

    void deleteWord(char *word)
    {
        Node *prev = this->root;
        vector<Node *> history;
        history.push_back(prev);
        for (char *it = word; *it != '\0'; ++it)
        {
            Node *curr = prev->next[*it - 'a'];
            if (curr == nullptr)
            {
                return;
            }
            history.push_back(curr);
            if (*(it + 1) == '\0')
            {
                --curr->count;
                if (curr->count == 0)
                {
                    // deleteBranch(history);
                }
            }
            prev = curr;
        }
    }

    int countWord(char *word)
    {
        Node *prev = this->root;
        for (char *it = word; *it != '\0'; ++it)
        {
            Node *curr = prev->next[*it - 'a'];
            if (curr == nullptr)
            {
                return 0;
            }
            prev = curr;
            if (*(it + 1) == '\0')
            {
                return prev->count;
            }
        }
        return 0;
    }

    int countSizeOfLongestPrefix(char *word)
    {
        int count = 0;
        Node *prev = this->root;
        for (char *it = word; *it != '\0'; ++it)
        {
            Node *curr = prev->next[*it - 'a'];
            if (curr == nullptr)
            {
                return count;
            }

            if (curr->c != *it)
            {
                break;
            }

            ++count;
            prev = curr;
        }
        return count;
    }
};

int op;
string word;
int main()
{
    Trie t;
    while (true)
    {
        fin >> op >> word;
        if (fin.eof())
        {
            break;
        }
        if (op == 0)
        {
            t.insertWord(&word[0]);
        }
        else if (op == 1)
        {
            t.deleteWord(&word[0]);
        }
        else if (op == 2)
        {
            fout << t.countWord(&word[0]) << "\n";
        }
        else if (op == 3)
        {
            fout << t.countSizeOfLongestPrefix(&word[0]) << "\n";
        }
    }
    return 0;
}