Cod sursa(job #2629305)

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

class Trie {
private:
    struct nod { ///declaratie structura auxiliara
        int numar_aparitii, nrurmasi;
        nod *muchii[26], *tata;
        nod() { ///ca noul nod sa fie clean
            numar_aparitii=nrurmasi=0; tata=nullptr;
            for(int i=0; i<26; i++) muchii[i]=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 pair <nod *, int> cauta_prefix(string & s) { ///returneaza nodul pana in care se potriveste si lungimea prefixului care se potriveste
        nod *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};
    }
public:
    Trie () { start=new nod(); }
    //~Trie() { dfs_delete(start); }
    inline 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()) {
            ptr->nrurmasi++;
            nod *nptr=new nod();
            nptr->tata=ptr;
            ptr->muchii[s[pozact]-'a']=nptr;
            ptr=nptr;
            pozact++;
        }
        ptr->numar_aparitii++; ///in caz ca aparitiile sunt considerate unice, ++ devine =1;
    }
    inline void remove_string(string s) { ///stergem string-ul
        pair <nod *, int> per=cauta_prefix(s);
        nod *ptr=per.first;
        int pozact=per.second;
        if(per.second!=(int)s.size()) return;
        ptr->numar_aparitii--;
        while(ptr->nrurmasi==0&&ptr->numar_aparitii==0&&ptr!=start) {
            ptr->tata->muchii[s[pozact-1]-'a']=nullptr;
            pozact--;
            ptr->tata->nrurmasi--;
            nod *temp=ptr->tata;
            delete ptr;
            ptr=temp;
        }
    }
    inline 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;
    }
    inline int search_string(string s) { ///cautam string-ul
        pair <nod *, int> per=cauta_prefix(s);
        return (per.second==(int)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;
        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;
}