Cod sursa(job #3251557)

Utilizator redstonegamer22Andrei Ion redstonegamer22 Data 26 octombrie 2024 11:05:13
Problema Trie Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.21 kb
#include <bits/stdc++.h>

using namespace std;

struct TrieNode {
    int frecventa;
    TrieNode* copii[26];

    TrieNode() {
        frecventa = 0;
        for(int i = 0; i < 26; ++i) {
            copii[i] = nullptr;
        }
    }
};

struct Trie {
    TrieNode* root;

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

    TrieNode* insert(TrieNode *r, string& s, int ind) {
        if(r == nullptr) {
            r = new TrieNode();
        }

        if(s.size() == ind) {
            r->frecventa += 1;
            return r;
        }

        int index = s[ind] - 'a';

        r->copii[index] = insert(r->copii[index], s, ind + 1);

        return r;
    }

    void insert(string s) {
        root = insert(root, s, 0);
    }

    int _search(TrieNode* nod, string& s, int ind) {
        if(nod == nullptr) return 0;

        if(s.size() == ind) return nod->frecventa;

        int index = s[ind] - 'a';

        if(nod->copii[index] == nullptr) {
            return 0;
        }
        return _search(nod->copii[index], s, ind + 1);
    }

    int search(string s) {
        return _search(root, s, 0);
    }

    TrieNode* erase(TrieNode* nod, string& s, int ind) {
        if(nod == nullptr) return nullptr;

        if(s.size() == ind) {
            nod->frecventa -= 1;
            nod->frecventa = max(nod->frecventa, 0);

            // Check if node can be deleted
            bool hasChild = false;
            for (int i = 0; i < 26; ++i) {
                if (nod->copii[i] != nullptr) {
                    hasChild = true;
                    break;
                }
            }

            if(!hasChild && nod->frecventa == 0) {
                delete nod;
                return nullptr;
            }

            return nod;
        }

        int index = s[ind] - 'a';

        TrieNode* copil = erase(nod->copii[index], s, ind + 1);

        nod->copii[index] = copil;

        // Check if node can be deleted
        bool hasChild = false;
        for (int i = 0; i < 26; ++i) {
            if (nod->copii[i] != nullptr) {
                hasChild = true;
                break;
            }
        }

        if(!hasChild && nod->frecventa == 0) {
            delete nod;
            return nullptr;
        }

        return nod;
    }

    void erase(string s) {
        root = erase(root, s, 0);
    }

    string find_lcp(string s) {
        string prefix = "";
        TrieNode* current_node = root;

        for(int i = 0; i < s.size() && current_node != nullptr; i++) {
            int index = s[i] - 'a';

            if(current_node->copii[index] == nullptr) {
                break;
            }

            prefix += s[i];
            current_node = current_node->copii[index];
        }

        return prefix;
    }
};

#ifndef LOCAL
ifstream in("trie.in");
ofstream out("trie.out");

#define cin in
#define cout out
#endif // LOCAL

int main() {
    int t; string s;

    Trie trie;

    while(cin >> t >> s) {
        // Read until end of file

        if(t == 0) {
            trie.insert(s);
        }
        if(t == 1) {
            trie.erase(s);
        }
        if(t == 2) {
            cout << trie.search(s) << '\n';
        }

        if(t == 3) {
            cout << trie.find_lcp(s).size() << '\n';
        }
    }
}