Pagini recente » Cod sursa (job #3216052) | Cod sursa (job #1698919) | Cod sursa (job #1324477) | Cod sursa (job #2902735) | Cod sursa (job #1458667)
#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;
}