Cod sursa(job #2629293)

Utilizator stefan.popescuPopescu Stefan stefan.popescu Data 19 iunie 2020 21:37:15
Problema Trie Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.73 kb
#include <iostream>
#include <fstream>
using namespace std;

class Trie
{
//public:

private:
    struct nod  ///-------------------declaratie structura auxiliara-------------------///
    {
        int numar_aparitii;
        nod *muchii[26];
        nod *tata;
        nod() ///ca noul nod sa fie clean
        {
            numar_aparitii=0;
            for(int i=0; i<26; i++)
            {
                muchii[i]=nullptr;
            }
            tata=nullptr;
        }
    };

    nod *start;

    void dfs_delete(nod * act) ///ca sa scap de trie in caz de ceva
    {
        for(int i=0; i<26; i++)
        {
            if(act->muchii[i]!=nullptr)
                dfs_delete(act->muchii[i]);
        }
        delete act;
    }

    inline bool isBasic(nod * ptr) ///verifica daca nodul e inutil
    {
        if(ptr->numar_aparitii!=0) return false;
        else
        {
            for(int i=0; i<26; i++)
            {
                if(ptr->muchii[i]!=nullptr) return false;
            }
        }
        return true;
    }
    pair <nod *, int> cauta_prefix(string & s) ///returneaza nodul pana in care se potriveste si lungimea prefixului care se potriveste
    {
        nod *ptr;
        ptr=start;
        int pozact=0;
        while(pozact<(int)s.size())
        {
            if(ptr->muchii[s[pozact]-'a']==nullptr)
                break;
            else
            {
                ptr=ptr->muchii[s[pozact]-'a'];
                ++pozact;
            }
        }
        return {ptr, pozact};
    }
    void sterge_sir(string & s, int pozact, nod * ptract)  ///se presupune ca exista sirul
    {
        //cout<<pozact<<endl;
        if(pozact==(int)s.size())
        {
            ptract->numar_aparitii--;
            if(isBasic(ptract)==true&&ptract!=start)
            {
                ptract->tata->muchii[s[pozact-1]-'a']=nullptr;
                delete ptract;
            }
            return;
        }
        sterge_sir(s, pozact+1, ptract->muchii[s[pozact]-'a']);
        if(isBasic(ptract)==true&&ptract!=start)
        {
            ptract->tata->muchii[s[pozact-1]-'a']=nullptr;
            delete ptract;
        }
    }

public:
    Trie ()
    {
        start=new nod();
    }
    ~Trie()
    {
        dfs_delete(start);
    }

    void add_string(string s) ///adaugam string-ul
    {
        pair <nod *, int> per=cauta_prefix(s);

        nod *ptr=per.first;
        int pozact=per.second;

        while(pozact<(int)s.size())
        {
            nod *nptr=new nod();
            nptr->tata=ptr;
            ptr->muchii[s[pozact]-'a']=nptr;
            ptr=nptr;
            pozact++;
        }

        ptr->numar_aparitii++; ///in caz ca aparitiile sunt unice, ++ devine =1;
    }

    void remove_string(string s) ///stergem string-ul
    {
        sterge_sir(s, 0, start);
    }

    int longest_prefix(string s) ///cel mai lung prefix comun cu un cuvant deja existent
    {
        pair <nod *, int> per=cauta_prefix(s);
        return per.second;
    }

    int search_string(string s) ///cautam string-ul
    {
        pair <nod *, int> per=cauta_prefix(s);
        return (per.second==s.size()) ? per.first->numar_aparitii : 0;
    }

};
ifstream in ("trie.in");
ofstream out("trie.out");
int op;
string sir;
int main()
{
    Trie arb;
    while(in>>op)
    {
        in>>sir;
        //cout<<sir<<endl;
        switch (op)
        {
            case 0: {arb.add_string(sir); break;}
            case 1: {arb.remove_string(sir); break;}
            case 2: {out<<arb.search_string(sir)<<"\n"; break;}
            case 3: {out<<arb.longest_prefix(sir)<<"\n"; break;}
        }
    }
    return 0;
}