Cod sursa(job #3231575)

Utilizator robert_dumitruDumitru Robert Ionut robert_dumitru Data 27 mai 2024 11:36:31
Problema Trie Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.91 kb
#include <bits/stdc++.h>
using namespace std;

/**
Trie
Este un arbore cu radacina in care etichetele
sunt pe muchii. Daca dorim sa memoram cuvinte,
atunci fiecare nod din arbore are cel mult 26
de legaturi catre fii:
leg[0] = legatura la 'a'
leg[1] = legatura la 'b'
...
leg[25] = legatura la 'z'

Daca avem toate cuvintele de exact 5 litere in trie,
atunci arborele nostru are (26^5-1)/25 de noduri

Operatii in trie:
- adaugare cuvant
- stergere cuvant
- cautare cuvant
- cautare cel mai lung prefix al unui cuvant in trie
*/

struct Nod
{
public:
    int nr; /// numarul de aparitii ale unui cuvant care se termina
            /// in acest nod
    int cnt; /// numarul de cuvinte care au prefixul pana in acest nod
    Nod *leg[26]; /// leg[0]='a', ..., leg[25] = 'z'
    Nod()
    {
        nr = cnt = 0;
        for (int i = 0; i < 26; i++)
            leg[i] = NULL;
    }
};

class Trie
{
public:
    Nod *rad;
    Trie()
    {
        rad = new Nod();
    }
    /// adauga cuvantul w in trie
    void Add(string w)
    {
        Nod *p, *q;
        int j, i, len = w.length();
        p = rad;
        for (i = 0; i < len; i++)
        {
            (p->cnt)++;
            j = w[i] - 'a';
            if (p->leg[j] == NULL)
            {
                q = new Nod;
                p->leg[j] = q;
            }
            p = p->leg[j];
        }
        (p->nr)++;
        (p->cnt)++;
    }

    /// sterge cuvantul w din trie
    void Erase(string w)
    {
        Nod *p;
        int j, i, len = w.length();
        p = rad;
        for (i = 0; i < len; i++)
        {
            (p->cnt)--;
            j = w[i] - 'a';
            p = p->leg[j];
        }
        (p->nr)--;
        (p->cnt)--;
    }

    /// de cate ori apare cuvantul w in trie
    int Count(string w)
    {
        Nod *p;
        int j, i, len = w.length();
        p = rad;
        for (i = 0; i < len; i++)
        {
            j = w[i] - 'a';
            if (p->leg[j] == NULL)
                return 0;
            p = p->leg[j];
        }
        return p->nr;
    }

    /// lungimea maxima a unui prefix
    int Prefix(string w)
    {
        if (rad->cnt == 0) return 0;
        Nod *p;
        int lgmax = 0, j, i, len = w.length();
        p = rad;
        for (i = 0; i < len; i++)
        {
            j = w[i] - 'a';
            if (p->leg[j] == NULL)
                return lgmax;
            p = p->leg[j];
            if (p->cnt == 0) return lgmax;
            lgmax++;
        }
        return lgmax;
    }
};

ifstream fin("trie.in");
ofstream fout("trie.out");

int main()
{
    int op;
    string w;
    Trie T;
    while (fin >> op >> w)
    {
        if (op == 0) T.Add(w);
        else if (op == 1)T.Erase(w);
        else if (op == 2)fout << T.Count(w) << "\n";
        else fout << T.Prefix(w) << "\n";
    }
    return 0;
}