Cod sursa(job #1458667)

Utilizator petru.cehanCehan Petru petru.cehan Data 8 iulie 2015 11:40:46
Problema Trie Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.81 kb
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

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

struct Trie
{
    int prefixes_count ; // numarul de cuvinte ce au ca prefix stringul curent ( din varful arborelui pana la acel nod )
    int words_count ; //  numarul de cuvinte care se potrivesc exact cu stringul dat ( sunt identice )
    Trie * child [26] ; // fiecare nod are un numar de copii egal cu dimensiunea alfabetului folosit ( orice nod poate sa aiba ca fiu
                                                                                                      // orice litera )
} ;

Trie * head ;

void Initialize ()
{
    head = new Trie () ;
    head->prefixes_count = 0 ;
    head->words_count = 0 ;
    for ( unsigned int i = 0 ; i < 27 ; ++ i )
           head -> child [i] = 0 ;  // NULL
}

void Insert ( string word , Trie * current ) // current la apel va fi defapt head ;
{

    int letter ; // aici calculez pozitia fiecarei litere in alfabet ;

    for ( unsigned int i = 0 ; i < word.size () ; ++ i )
       {
           letter = word[i] - 'a' ;
           if ( current -> child [ letter ] == 0 )
                      ++ current->prefixes_count , current -> child [ letter ] = new Trie () ;
           current = current -> child [ letter ] ;
       }
    ++ current -> words_count ;

}

bool Delete ( string word , Trie * current )
// daca apare de mai mult de 1 data  , decrementez doar words_count "din ultimul nod"
// altfel merg pana la ultima litera din cuvant ( nodul ce contine ultima litera ) si ma intorc pe recursie doar daca am sters acel nod
// repet acest lucru pana cand nu am mai putut sterge , fie din cauza ca existau mai multe cuvinte ( dupa stergere, words_count >= 1 )
// , fie din cauza ca nodul la care am ajuns este litera in alt cuvant ( prefixes_count >= 1 inca , dupa stergere ) , fie ca e radacina trie-ului .
{
    if ( word.empty() == true )
        -- current -> words_count ;

    else
    {
          int letter = *word.begin() - 'a' ;
          word.erase ( word.begin () ) ;

          if ( Delete ( word , current -> child [ letter ] ) == true )
               {
                    current -> child [ letter ] = 0;
                    -- current -> prefixes_count ;
               }
    }

    if ( current -> words_count == 0 && current -> prefixes_count == 0 && current != head )
        {
            delete current ;
            return true ;
        }
    else
            return false ;

}

int GetNumberOfWords ( string word , Trie * current )  // numarul de aparitii al stringului word in lista
{
    int letter ;

    for ( unsigned int i = 0 ; i < word.size() ; ++ i )
       {
           letter = ( word[i] ) - 'a' ;
           if ( current -> child [ letter ] == 0 )
                    return 0 ;
           current = current -> child [ letter ] ;
       }

    return current -> words_count ;
}

int GetMaxPrefix ( string word , Trie * current )  // lungimea celui mai lung prefix comun
{
    int letter ;

    for ( unsigned int i = 0 ; i < word.size() ; ++ i )
       {
           letter = ( word[i] ) - 97 ;
           if ( current -> child [ letter ] == 0 )
                    return i ;
           current = current -> child [ letter ] ;
       }

    return word.size () ;
}

int main()
{
    int op ;
    string str ;

    Initialize () ;

    while ( fin >> op >> str )

    {
         switch ( op )
         {
            case 0 : Insert ( str , head ) ; break ;

            case 1 : Delete ( str , head ) ; break ;

            case 2 : fout << GetNumberOfWords ( str , head ) << '\n' ; break ;

            case 3 : fout << GetMaxPrefix ( str , head ) << '\n' ; break ;
         }
    }

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

    return 0;
}