Cod sursa(job #3151039)

Utilizator proflaurianPanaete Adrian proflaurian Data 19 septembrie 2023 15:46:41
Problema Trie Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.37 kb
#include <bits/stdc++.h>
using namespace std;
ifstream f("trie.in");
ofstream g("trie.out");
char cuv[25];
int tip;
struct nod
{
    int cnt,nr;/// cate cuvinte se termina in acest nod
    nod *s[26];/// lista succesorilor nodului ( de la 'a' la 'z' )
    /// contructor ... folosim pentru ca un nod construit sa aiba initial cnt=nr=0 si s[i]=NULL
    nod()
    {
        cnt=nr=0;
        for(int i=0;i<26;i++)
            s[i]=NULL;
    }
};
nod *root;
int main()
{
    root=new nod;
    /// nu stiu cate operatii am deci controlez din citiri cate operatii am !!!
    while(f>>tip) /// cat timp pot citi ceva din fisier, acel ceva este tipul operatiei
    {
        /// citesc cuvantul caruia i se aplica operatia
        f>>cuv;

        if(tip==0)///insertie cuvant
        {
            nod *X=root; /// cu X parcurg trie
            char *p=cuv; /// cu p parcurg cuvantul
            while(*p)/// cat timp am litera ( nu am parcurs inca cuvantul )
            {
                int i=*p-'a';/// i = "numarul de ordine al literei" ( intre 0='a' si 25='z' )
                /// verific daca am deja link spre acea litera si daca nu am creez
                if(X->s[i]==NULL) X->s[i]=new nod;
                X=X->s[i];/// avansez in trie spre acea litera
                X->nr++;///
                p++;/// trec la urmatoarea litera urmatoare
            }
            X->cnt++; /// la nodul la care am ajuns adaug inca o aparitie a cuvantului
        }
        if(tip==1)/// stergere cuvant
        {
            nod *X=root; /// cu X parcurg trie
            char *p=cuv; /// cu p parcurg cuvantul
            while(*p)
            {
                int i=*p-'a';
                X=X->s[i];
                X->nr--;
                p++;
            }
            X->cnt--;
        }
        if(tip==2)/// numara aparitii cuvant
        {
            nod *X=root; /// cu X parcurg trie
            char *p=cuv; /// cu p parcurg cuvantul
            while(*p)
            {
                int i=*p-'a';
                X=X->s[i];
                if(X==NULL||X->nr==0)
                    break;
                p++;
            }
            if(X==NULL)
                g<<"0\n";
            else
                g<<X->cnt<<'\n';
        }
        if(tip==3)/// calculeaza lungime prefix maxim comun cu cuvintele din trie
        {
            nod *X=root; /// cu X parcurg trie
            char *p=cuv; /// cu p parcurg cuvantul
            int lg=0;
            while(*p)
            {
                int i=*p-'a';
                X=X->s[i];
                if(X==NULL||X->nr==0)
                    break;
                p++;lg++;
            }
            g<<lg<<'\n';
        }

    }
    return 0;
}
/// initial trie vid <=> radacina este NULL !!!
/// operatii:
    /// adauga cuvant:
        /// plecam din radacina si parcurgem simultan cuvantul si trie
        /// cand sunt intr-un nod:
            ///verific daca nodul are creata legatura spre litera la care am ajuns
                /// daca nu are se creaza
            /// avansez in trie pe acea legatura
            /// avansez in cuvant la urmatoarea litera
        /// cand am ajuns la finalul cuvantului - adaug o unitate la contorul nodului
/// numara aparitiile unul cuvant dat
    /// se parcurge simultan cuvantul si trie
        /// daca la un moment dat nu am legatura spre litera la care am ajuns in cuvant,
            /// atunci nu exista cuvantul in trie - numarul de aparitii este 0
        /// daca ajung la ultima litera atunci contorul din nodul la care am ajuns indica
            /// de cate ori apare cuvantul
/// calculeaza prefixul maxim comun al unui cuvant
    /// se parcurg simultan cuvantul si trie
        /// pentru fiecare litera pe care o parcurg adaug o unitate la lungimea prefixului
        /// daca am terminat cuvantul sau nu am legatura spre litera la care am ajuns ma opresc
        /// si afisez lungimea calculata
/// sterge cuvant
    /// se parcurge simultan cuvantul si trie
        /// scad o unitate din contor

/// OPTIMIZARE LA STERGERE
    /// adaug un camp la nod care numara cate cuvinte trec prin nod
    /// atunci cand sterg cuvantul scad o unitate din valaorea acelui camp
    /// daca valoarea ajunge la 0 atunci pe acolo nu mai trece niciun cuvant
    /// orice nod care are acea valoare 0 poate fi "eliminat" din trie