Cod sursa(job #2653186)

Utilizator razvan242Zoltan Razvan-Daniel razvan242 Data 27 septembrie 2020 12:24:31
Problema Trie Scor 5
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3 kb
#include <iostream>
#include <fstream>
#include <algorithm>

using namespace std;

string name = "trie";
ifstream fin(name + ".in");
ofstream fout(name + ".out");

const int SIGMA = 26;

struct TrieNode {
    TrieNode* fii[SIGMA] = {};
    int nrFii = 0;
    int nrCuvinte = 0;
};

TrieNode *root;

void adaugaCuvant(TrieNode *node, string cuvant) {
    if (cuvant.size() == 0) {
        /// nod terminal - daca ramanem fara litere
        /// inseamna ca nodul actual simbolizeaza sfarsitul cuvantului
        ++node->nrCuvinte;
        return;
    }

    int pos = cuvant[0] - 'a';
    if (node->fii[pos] == nullptr) {
        node->fii[pos] = new TrieNode;
        ++node->nrFii;
    }
    /// mergem in nodul corespondent primei litere din cuvant
    /// cu cuvantul fara prima litera
    adaugaCuvant(node->fii[pos], cuvant.substr(1));
}

int nrAparitiiCuvant(TrieNode* node, string cuvant) {
    if (node == nullptr) {
        return 0;
    }
    if (cuvant.size() == 0) {
        return node->nrCuvinte;
    }
    int pos = cuvant[0] - 'a';
    string cuvantNou = cuvant.substr(1);
    return nrAparitiiCuvant(node->fii[pos], cuvantNou);
}

int lungimePrefix(TrieNode* node, string cuvant) {
    if (cuvant.size() == 0) {
        /// intreg cuvantul e prefix
        return 0;
    }
    if (node == nullptr) {
        return -1;
    }
    //fout << cuvant << '\n';
    int pos = cuvant[0] - 'a';
    string cuvantNou = cuvant.substr(1);
    return 1 + lungimePrefix(node->fii[pos], cuvantNou);
}

bool stergeCuvant(TrieNode* node, string cuvant) {
    if (node == nullptr) {
        return false;
    }
    if (cuvant.size() == 0) {
        --node->nrCuvinte;
        if (node->nrCuvinte == 0 && node->nrFii == 0) {
            delete node;
            return true;
        }
        else {
            return false;
        }
    }

    int pos = cuvant[0] - 'a';
    bool amStersNod = stergeCuvant(node->fii[pos], cuvant.substr(1));
    if (amStersNod) {
        --node->nrFii;
        node->fii[pos] = nullptr;
        if (node->nrFii == 0) {
            delete node;
            return true;
        }
    }
    return false;
}

void dezalocaTrie(TrieNode* node) {
    if (node == nullptr) {
        return;
    }
    for (int i = 0; i < SIGMA; ++i) {
        dezalocaTrie(node->fii[i]);
    }
    delete node;
}

int main()
{
    int op;
    string s;


    while (fin >> op >> s) {
        if (root == nullptr) {
            root = new TrieNode;
        }
        if (op == 0) {
            adaugaCuvant(root, s);
        }
        else if (op == 1) {
            bool stersRadacina = stergeCuvant(root, s);
            if (stersRadacina) {
                root = nullptr;
            }
        }
        else if (op == 2) {
            fout << nrAparitiiCuvant(root, s) << '\n';
        }
        else if (op == 3) {
            fout << lungimePrefix(root, s) << '\n';
        }
    }
    dezalocaTrie(root);
    return 0;
}