Pagini recente » Cod sursa (job #670358) | Cod sursa (job #2571224) | Cod sursa (job #1703481) | Cod sursa (job #540410) | Cod sursa (job #3231584)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("trie.in");
ofstream fout("trie.out");
/**
Trie
Este un arbore cu radacina in care etichetele
sunt pe muchii. Daca dorim sa memoram cuvinte,
atunci fiecare nod din arbore are cel mult 26
de legaturi catre fii:
leg[0] = legatura la 'a'
leg[1] = legatura la 'b'
...
leg[25] = legatura la 'z'
Daca avem toate cuvintele de exact 5 litere in trie,
atunci arborele nostru are (26^5-1)/25 de noduri
Operatii in trie:
- adaugare cuvant
- stergere cuvant
- cautare cuvant
- cautare cel mai lung prefix al unui cuvant in trie
*/
struct Nod
{
public:
int nr; /// numarul de aparitii ale unui cuvant care se termina
/// in acest nod
int cnt; /// numarul de cuvinte care au prefixul pana in acest nod
Nod *leg[26]; /// leg[0]='a', ..., leg[25] = 'z'
Nod()
{
nr = cnt = 0;
for (int i = 0; i < 26; i++)
leg[i] = NULL;
}
};
class Trie
{
public:
Nod *rad;
Trie()
{
rad = new Nod();
}
/// adauga cuvantul w in trie
void Add(string w)
{
Nod *p, *q;
int j, i, len = w.length();
p = rad;
for (i = 0; i < len; i++)
{
(p->cnt)++;
j = w[i] - 'a';
if (p->leg[j] == NULL)
{
q = new Nod;
p->leg[j] = q;
}
p = p->leg[j];
}
(p->nr)++;
(p->cnt)++;
}
/// sterge cuvantul w din trie
void Erase(string w)
{
Nod *p;
int j, i, len = w.length();
p = rad;
for (i = 0; i < len; i++)
{
(p->cnt)--;
j = w[i] - 'a';
p = p->leg[j];
}
(p->nr)--;
(p->cnt)--;
}
/// de cate ori apare cuvantul w in trie
int Count(string w)
{
Nod *p;
int j, i, len = w.length();
p = rad;
for (i = 0; i < len; i++)
{
j = w[i] - 'a';
if (p->leg[j] == NULL)
return 0;
p = p->leg[j];
}
return p->nr;
}
/// lungimea maxima a unui prefix
int Prefix(string w)
{
if (rad->cnt == 0) return 0;
Nod *p;
int lgmax = 0, j, i, len = w.length();
p = rad;
for (i = 0; i < len; i++)
{
j = w[i] - 'a';
if (p->leg[j] == NULL)
return lgmax;
p = p->leg[j];
if (p->cnt == 0) return lgmax;
lgmax++;
}
return lgmax;
}
};
int main()
{
Trie T;
int op;
string cuv;
while(fin>>op>>cuv)
{
switch(op)
{
case 0: T.Add(cuv); break;
case 1: T.Erase(cuv); break;
case 2: fout<< T.Count(cuv)<<"\n"; break;
case 3: fout<<T.Prefix(cuv)<<"\n"; break;
}
}
return 0;
}