Cod sursa(job #2742169)

Utilizator Elena_Florina_MarinasElena-Florina Marinas Elena_Florina_Marinas Data 20 aprilie 2021 13:20:21
Problema Trie Scor 5
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.91 kb
#include <bits/stdc++.h>
#define L_ALF 30
using namespace std;

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


struct trie
{
    trie *fii[L_ALF];
    int nr_ap_cuvant, nr_fii;
};

/*
nr_ap_cuvant = 0 inseamna ca nu s-a sfarsit cuvantul - nodul e o litera din interiorul cuvantului;
nr_ap_cuvant = 1, 2, 3 etc. inseamna de cate ori a fost introdus cuvantul in trie;
nr_fii - contorizez cati fii are din cei 26 posibili;
fii[i] - pointer catre un alt subarbore care contine cuvinte ce au prefixul format din
         literele pana la litera din nodul curent si continua cu litera nr i din alfabet
    (vezi: https://www.youtube.com/watch?v=-otwLNjYN7w )
*/

trie *t = new trie;

trie* aloca_mem_nod()
{
    trie *nod_nou = new trie;
    nod_nou->nr_fii = 0;
    nod_nou->nr_ap_cuvant = 0;

    for(int i = 0; i < L_ALF; i++)
    {
        nod_nou->fii[i] = NULL;
    }

    return nod_nou;
}

void adauga(trie *t, char *s)
{
    int n = strlen(s);
    int indice_litera;

    for(int i = 0; i < n - 1; i++)
    {
        indice_litera = s[i] - 'a';
        if(t->fii[indice_litera] == NULL)
        {
            t->fii[indice_litera] = aloca_mem_nod();
            t->nr_fii++;

        }
        t = t->fii[indice_litera];
    }

    // la ultima litera anuntam ca s-a incheiat un cuvant:
    indice_litera = s[n - 1] - 'a';
    if(t->fii[indice_litera] == NULL)
    {
        t->fii[indice_litera] = aloca_mem_nod();
        t->nr_fii++;
        t->fii[indice_litera]->nr_ap_cuvant = 1;
    }
    else
    {
        t->fii[indice_litera]->nr_ap_cuvant++;
    }

}

int nr_aparitii(trie *t, char *cuvant)
{
    int n = strlen(cuvant);
    int indice_litera;

    for(int i = 0; i < n - 1; i++)
    {
        indice_litera = cuvant[i] - 'a';
        if(t->fii[indice_litera] == NULL)
        {
            return 0;
        }

        t = t->fii[indice_litera];
    }

    indice_litera = cuvant[n - 1] - 'a';
    if(t->fii[indice_litera] == NULL || t->fii[indice_litera]->nr_ap_cuvant == 0)
    {
        return 0;
    }

    return t->fii[indice_litera]->nr_ap_cuvant;
}


int lung_prefix(trie *t, char *cuvant)
{
    int i = -1;

    while(t)
    {
        i++;
        t = t->fii[cuvant[i] - 'a'];
    }

    return i;
}


void sterge2(trie *t, char *cuvant, int i, int &stop)
{
    int n = strlen(cuvant);
    if(stop == 0)
    {
        if(i <= n - 2)
        {
            sterge2(t->fii[cuvant[i + 1] - 'a'], cuvant, i + 1, stop);
            if(stop == 0)
            {
                t->nr_fii--;
                trie *nod = t->fii[cuvant[i + 1] - 'a'];
                if(nod)
                {
                    delete nod;
                    t->fii[cuvant[i + 1] - 'a'] = NULL;
                }

                if(t->nr_fii >= 1)
                {
                    stop = 1;
                }
            }
        }
        else    // am ajuns la ultima litera
        {
            if(t->nr_ap_cuvant > 1 || t->nr_fii > 0)
            {
                t->nr_ap_cuvant--;
                stop = 1;
            }
        }
    }
}


int main()
{
    char sir[32];

    t = aloca_mem_nod();

    while(fin.getline(sir, 32))
    {
        if(sir[0] == '0')
        {
            adauga(t, sir + 2);
        }
        else
        {
            if(sir[0] == '2')
            {
                fout << nr_aparitii(t, sir + 2) << "\n";
            }
            else
            {
                if(sir[0] == '3')
                {
                    fout << lung_prefix(t, sir + 2) << "\n";
                }
                else
                {
                    if(sir[0] == '1')
                    {
                        int stop = 0;
                        sterge2(t, sir + 2, -1, stop);
                    }
                }
            }
        }
    }

    return 0;
}