Cod sursa(job #3151822)

Utilizator cdenisCovei Denis cdenis Data 22 septembrie 2023 22:53:18
Problema Trie Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.95 kb
#include <fstream>
#include <string>
#include <stack>
#include <cstring>

using namespace std;

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

struct TrieNode {
    int endCount, childrenCount;
    TrieNode *v[26];
    TrieNode(int endCount = 0, int childrenCount = 0) : endCount(endCount), childrenCount(childrenCount)
    {
        for (int i = 0; i < 26; i++) {
            v[i] = nullptr;
        }
    }
};

class Trie {
private:
    TrieNode *root;

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

    void dfs(TrieNode *curr)
    {
        if (!curr) {
            return;
        }

        for (int i = 0; i < 26; i++) {
            if (curr->v[i]) {
                dfs(curr->v[i]);
                delete curr->v[i];
            }
        }
    }

    ~Trie()
    {
        dfs(root);
        delete root;
    }

    void insert(string word)
    {
        TrieNode *curr = root;
        for (int i = 0; i < word.size(); i++) {
            char letter = word[i];
            if (!curr->v[letter - 'a']) {
                curr->childrenCount++;
                curr->v[letter - 'a'] = new TrieNode();
            }
            curr = curr->v[letter - 'a'];
        }
        curr->endCount++;
    }

    bool remove(TrieNode *curr, char *word)
    {
        if (*word == '\0')
            curr->endCount--;
        else if (remove(curr->v[*word - 'a'], word + 1)) {
            curr->v[*word - 'a'] = 0;
            curr->childrenCount--;
        }
        if (curr->endCount == 0 && curr->childrenCount == 0 && curr != root) {
            delete curr;
            return 1;
        }
        return 0;
    }

    void remove(string word)
    {
        char *c_word = new char[word.size() + 1];
        strcpy(c_word, word.c_str());
        remove(root, c_word);
        delete c_word;
    }

    int search(string word)
    {
        TrieNode *curr = root;
        for (auto letter : word) {
            if (curr->v[letter - 'a']) {
                curr = curr->v[letter - 'a'];
            } else {
                return 0;
            }
        }
        return curr->endCount;
    }

    int longestPrefix(string word)
    {
        int length = 0;
        TrieNode *curr = root;
        for (auto letter : word) {
            if (curr->v[letter - 'a']) {
                curr = curr->v[letter - 'a'];
                length++;
            } else {
                return length;
            }
        }
        return length;
    }
};

int main()
{
    Trie *trie = new Trie();
    int operation_id;
    string word;
    while (cin >> operation_id >> word) {
        switch (operation_id) {
        case 0:
            trie->insert(word);
            break;

        case 1:
            trie->remove(word);
            break;

        case 2:
            cout << trie->search(word) << '\n';
            break;

        case 3:
            cout << trie->longestPrefix(word) << '\n';
            break;

        default:
            break;
        }
    }
    delete trie;
    return 0;
}