Cod sursa(job #2342056)

Utilizator andreigeorge08Sandu Ciorba andreigeorge08 Data 12 februarie 2019 16:17:03
Problema Trie Scor 100
Compilator cpp-32 Status done
Runda Arhiva educationala Marime 3.04 kb
#include <bits/stdc++.h>

using namespace std;

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

char cuv[21];

struct Nod
{
    int cnt, nr;
    Nod *fii[26];
};

Nod *T;

void Insert(char s[])
{
    int x;
    Nod *p, *q;
    p = T;

    for(int i = 0; s[i]; i++)
    {
        x = s[i] - 'a'; ///mapez valorile de tip caracter
        /// la valori intre 0  si 25

        if(p->fii[x] != 0) ///daca deja exista calea
        {
            p = p->fii[x];/// ma mut pe nod
            p->cnt++;///adun la nr de aparitii
        }
        else ///daca nu exista legatura
        {
            /// o creez
            q = new Nod;
            q->nr = 0;
            q->cnt = 1; /// aceasta litera apare o singura data
            /// momentan

            for(int j = 0; j < 26; j++) q->fii[j] = 0;
            ///initializez fiii

            p->fii[x] = q; ///s-a creat legatura dintre nodul acesta
            ///si cel curent
            p = p->fii[x];/// ma mut in jos, nodul
            ///de-abia pus devenind cel curent
        }
    }

    p->nr++; ///aici se termina cuvantul
    ///pus asa ca voi contoriza cuvantul
}

void Delete(char s[])
{
    ///stergerea consta in eliminarea
    ///unei aparitii a fiecarei litere din
    /// trie;
    /// NU se verifica existenta cuvantului
    /// deoarece se mentioneaza
    /// faptul ca daca se apeleaza delete
    /// cuvantul va exista cel putin o data
    int x;
    Nod *p;
    p = T;

    for(int i = 0; s[i]; i++) ///parcurg literele
    {
        x = s[i] - 'a';
        p = p->fii[x]; ///ma duc pe litera
        p->cnt--;/// si ii sterg o frecventa
    }
    p->nr--; ///sterg aparitia acestui cuvant
}

void NrAparitii(char s[])
{
    int x;
    Nod *p;
    p = T;

    for(int i = 0; s[i]; i++)
    {
        x = s[i] - 'a';
        if(p->fii[x] == NULL || p->fii[x]->cnt == 0)
        {
            fout << "0\n";
            return;
        }
        p = p->fii[x]; ///parcurg fiii pana ajung
    }
    /// la finalul cuvantului
    /// ultimul nod al acestui lant
    /// cuprinzand numarul de cuvinte
    /// ce se termina la acel nod

    fout << p->nr << "\n";
}

void Prefix(char s[])
{
    int x, sol = 0;
    Nod *p;
    p = T;

    for(int i = 0; s[i]; i++)
    {
        x = s[i] - 'a';
        if(p->fii[x] == NULL || p->fii[x]->cnt == 0)
        {
            ///daca nu exista legatura sau
            ///litera urmatoare
            ///afisez lungimea obtinuta pana acum
            fout << sol << "\n";
            return;
        }
        sol++; ///contorizez lungimea
        p = p->fii[x];
    }

    fout << sol << "\n";
}

int main()
{
    T = new Nod;
    T->cnt = T->nr = 0;
    for(int i = 0; i < 26; i++)
        T->fii[i] = 0;

    int op;

    while(fin >> op >> cuv)
    {
        if(op == 0)
            Insert(cuv);
        else if(op == 1)
            Delete(cuv);
        else if(op == 2)
            NrAparitii(cuv);
        else Prefix(cuv);
    }
    return 0;
}