Pagini recente » Cod sursa (job #1898395) | Istoria paginii blog/biografii-olimpici | Cod sursa (job #527809) | Cod sursa (job #1425418) | Cod sursa (job #1313259)
#include <bits/stdc++.h>
#include <malloc.h>
using namespace std;
const int SIGMA = 26;
const int NR_CELLS = 120000;
const int Lmax = 20;
struct __attribute__((__packed__)) ListNode
{
int value;
int letter:8;
ListNode* urm;
ListNode( const int v = 0, const int l = 0 )
{
value = v;
letter = l;
urm = NULL;
}
};
struct __attribute__((__packed__)) Trie
{
ListNode *head;
int nrAparitii;
char nrSons;
Trie()
{
nrSons = 0;
nrAparitii = 0;
head = NULL;
}
};
Trie T[NR_CELLS];
int root, size;
void initTrie()
{
root = 0;
size = root + 1;
}
void addToList( const int node, const int val, const int letter )
{
ListNode* newNode = new ListNode( val, letter );
if ( !T[node].head )
T[node].head = newNode;
else
{
newNode->urm = T[node].head;
T[node].head = newNode;
}
}
void eraseList( const int node )
{
ListNode* p = T[node].head;
while ( p )
{
ListNode* aux = p;
p = p->urm;
delete aux;
}
T[node].head = NULL;
}
void eraseFromList( const int node, const int letter )
{
if ( T[node].head == NULL )
return;
if ( T[node].head->letter == letter )
{
ListNode* p = T[node].head;
T[node].head = T[node].head->urm;
delete p;
}
else
{
ListNode* pred = T[node].head;
while ( pred->urm != NULL && pred->urm->letter != letter )
pred = pred->urm;
ListNode* deSters = pred->urm;
pred->urm = deSters->urm;
delete deSters;
}
}
int NEXT( const int node, const int letter )
{
ListNode* p = T[node].head;
while ( p != NULL )
{
if ( p->letter == letter )
return p->value;
p = p->urm;
}
return 0;
}
void insert( char *s )
{
int node = root;
for ( ; *s; s++ )
{
int ch = *s - 'a';
int urm = NEXT( node, ch );
if ( urm == 0 )
{
urm = size++;
addToList( node, urm, ch );
T[node].nrSons++;
}
node = urm;
}
T[node].nrAparitii++;
}
int stiva[Lmax + 1];
int top;
void erase( char *s )
{
int node = root;
top = 0;
for ( ; *s; s++ )
{
int ch = *s - 'a';
node = NEXT( node, ch );
assert( node != 0 );
stiva[ ++top ] = node;
}
T[node].nrAparitii--;
while ( T[node].nrAparitii == 0 && T[node].nrSons == 0 && node != root )
{
s--;
eraseList( node );
node = stiva[ --top ];
eraseFromList( node, *s - 'a' );
T[node].nrSons--;
}
}
int count( char *s )
{
int node = root;
for ( ; *s; ++s )
{
int ch = *s - 'a';
int urm = NEXT( node, ch );
if ( urm == 0 )
break;
else
node = urm;
}
if ( *s )
return 0;
else
return T[node].nrAparitii;
}
int prefix( char *s )
{
int sol = 0;
int node = root;
for ( ; *s; ++s )
{
int ch = *s - 'a';
int urm = NEXT( node, ch );
if ( urm == 0 )
break;
else
{
sol++;
node = urm;
}
}
return sol;
}
void validareTest()
{
ifstream in("trie.out");
ifstream ok("tests//grader_test20.ok");
if ( !in || !ok )
{
cerr << "File output/ok missing!";
exit( 0 );
}
int mySOl, correctSol;
while( in >> mySOl )
{
ok >> correctSol;
if ( mySOl != correctSol )
{
cerr << "Wrong Answer " << mySOl << " " << correctSol << "\n";
exit( 0 );
}
}
cerr << "Accepted\n";
in.close();
ok.close();
}
int main()
{
FILE *in = fopen("trie.in", "r");
FILE *out = fopen("trie.out", "w");
if ( !in )
{
cerr << "Missing input file\n";
exit( 0 );
}
initTrie();
int tip;
char s[Lmax + 1];
while ( fscanf( in, "%d %s", &tip, s ) == 2 )
{
switch ( tip )
{
case 0: insert( s ); break;
case 1: erase( s ); break;
case 2: fprintf(out, "%d\n", count( s )); break;
case 3: fprintf(out, "%d\n", prefix( s )); break;
}
}
fclose( in );
fclose( out );
///validareTest();
///malloc_stats(); /// MEMORY TEST
return 0;
}