Cod sursa(job #2725580)

Utilizator calinfloreaCalin Florea calinflorea Data 19 martie 2021 11:17:21
Problema Trie Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.06 kb
#include <iostream>
#include <fstream>

/**
am ales sa implementez problema din arhiva educationala infoarena
am mai facut acest algoritm in liceu pt olimpiada de informatica
in plus fata de solutia de la lab este faptul ca eu am cuvinte de lungime variabila
si eu voi returna de cate ori apar cuvintele nu doar le caut
si faptul ca virgula caut si prefixe de cuvinte daca este nevoie
am obtinut 100 de puncte :)
https://www.infoarena.ro/problema/trie
*/

using namespace std;

ifstream fin ("trie.in");
ofstream fout ("trie.out");
char cuv[21];
struct Nod
{
    int cnt , nr;
    Nod * leg[26];
};

Nod * L;

void Insert(const char cuv[])
{
    int x;
    Nod *p , *q;
    p = L;
    ///p = nodul literei curente in arbore
    ///q = nodul de care ne folosim la inserari
    for(int i = 0 ; cuv[i] ; i++)
    {
        x = cuv[i] - 'a';
        if(p -> leg[x] != 0)
        {
            p = p -> leg[x];
            p -> cnt++;
        }
        else
        {
            q = new Nod;
            q -> nr = 0;
            q -> cnt = 1;
            for(int j = 0 ; j < 26 ; j++)
                q -> leg[j] = 0;
            p -> leg[x] = q;
            p = q;
        }
    }
    ///am ajuns in capat cu cuvantul, contorizam in nr de cate ori apare
    p -> nr++;
}

void Delete(const char cuv[])
{
    int x;
    Nod *p;
    p = L;
    ///cobor in arbore pana gasesc cuvantul final
    for(int i = 0 ; cuv[i] ; i++)
    {
        x = cuv[i] - 'a';
        p = p -> leg[x];
        p -> cnt--;
    }
    ///nr scade, cuvantul pierde din contorizari
    p -> nr--;
}

int FindCuvant(const char cuv[])
{
    int x;
    Nod *p;
    p = L;
    ///cobor in arbore pana gasesc intreg cuvantul
    for(int i = 0 ; cuv[i] ; i++)
    {
        x = cuv[i] - 'a';
        if(p -> leg[x] == 0)
            return 0;
        p = p -> leg[x];
    }
    ///daca nr - 0 inseamna ca nu este cuvantul intreg, e doar un prefix
    return (p -> nr);
}

inline int FindPrefix(const char cuv[])
{
    int x , ans = 0;
    Nod *p;
    p = L;

    ///cobor in arbore si verific cate prefixe pot gasi
    ///la fiecare coborare reusita numarul de prefixe creste
    for(int i = 0 ; cuv[i] ; i++)
    {
        x = cuv[i] - 'a';
        if(p -> leg[x] == 0 || p -> leg[x] -> cnt == 0)
            return ans;
        ans++;
        p = p -> leg[x];
    }
    return ans;
}

int main()
{
    int op;
    L = new Nod;
    L -> cnt = 0;
    L -> nr = 0;

    for(int i = 0 ; i < 26 ; i++)
        L -> leg[i] = 0;

    while(fin >> op >> cuv)
    {
        ///inserarea unui cuvant
        if(op == 0)
            Insert(cuv);
        ///stergerea unui cuvant
        else if(op == 1)
            Delete(cuv);
        ///cautarea cuvantului cuv (returneaza numarul de elemente)
        else if(op == 2)
            fout << FindCuvant(cuv) << "\n";
        ///cautarea prefixelor lui cuv (returneaza nr. de elemente)
        else fout << FindPrefix(cuv) << "\n";
    }

    fin.close();
    fout.close();

    return 0;
}