Cod sursa(job #2156725)

Utilizator ifrimencoAlexandru Ifrimenco ifrimenco Data 8 martie 2018 22:48:21
Problema Trie Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.94 kb
#include <iostream>
#include <fstream>
#include <cstring>
#include <string>

using namespace std;

const int sigma = 26;
struct Trie {
        void eliberare(Trie *poz);
        int nrp; /// nr parcurgeri
        int cuv; /// cuvintele care se termina in nodul curent
        Trie* urm[sigma]; /// cele 26 de ramuri (26 litere din alfabet)
        Trie() {/// constructor
            nrp = 0;
            cuv = 0;
            for (int i = 0; i < sigma; ++i)
                urm[i] = NULL;
        }
        inline void adaugare(string word);
        inline void stergere(string word);
        inline int nrcuvinte(string word);
        inline int lung_pref(string word);
};

Trie *root = new Trie;

void Trie :: eliberare(Trie *poz) { ///eliberare memorie (se leapada de pacate)
    for (int i = 0; i < sigma; ++i) {
        if (poz->urm[i])
            eliberare(poz->urm[i]);
    }
    delete poz;
}

inline void Trie :: adaugare(string word) {
    Trie *poz = root;
    Trie *next;
    for (unsigned int i = 0; i < word.size(); ++i) {
        int l = word[i] - 'a';
        next = poz->urm[l];
        if (next == NULL) {
            next = new Trie;
            poz->urm[l] = next;
        }
        next->nrp++;
        if (i == word.size() - 1) next->cuv++;
        poz = next;
    }
}

inline void Trie :: stergere(string word) {
    Trie *poz = root;
    Trie *next;
    poz->nrp--;
    for (unsigned int i = 0; i < word.size(); ++i) {
        int l = word[i] - 'a';
        next = poz->urm[l];
        next->nrp--;
        if (next->nrp == 0) {
            root->eliberare(next);
            poz->urm[l] = NULL;
            break;
            }
        else {
        if (i == word.size() - 1) next->cuv--;
        poz = next;
        }
    }
}

inline int Trie :: nrcuvinte(string word) {
    Trie *poz = root;
    Trie *next;
    for (unsigned int i = 0; i < word.size(); ++i) {
        int l = word[i] - 'a';
        next = poz->urm[l];
        if (next == NULL) return 0;
        if (i == word.size() - 1) return next->cuv;
        poz = next;
    }
}

inline int Trie :: lung_pref(string word) {
    Trie *poz = root;
    Trie *next;
    for (unsigned int i = 0; i < word.size(); ++i) {
        int l = word[i] - 'a';
        next = poz->urm[l];
        if (next == NULL) return i;
        if (i == word.size() - 1) return i + 1;
        poz = next;
    }
}

int main()
{
    ifstream fin("trie.in");
    ofstream fout("trie.out");
    string x; int i;
    while (fin >> i >> x) {
        switch(i) {
            case 0:
                root->adaugare(x);
                break;
            case 1:
                root->stergere(x);
                break;
            case 2:
                fout << root->nrcuvinte(x) << "\n";
                break;
            case 3:
                fout << root->lung_pref(x) << "\n";
                break;
        }
    }
    return 0;

}