Cod sursa(job #1313117)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 10 ianuarie 2015 12:24:59
Problema Trie Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 3.13 kb
#include <bits/stdc++.h>

using namespace std;

const int SIGMA = 26;
const int NR_CELLS = 120000;
const int Lmax = 20;

struct __attribute__((__packed__)) Trie
{
    int *sons;
    int nrAparitii;
    char nrSons;

    Trie()
    {
        nrSons = 0;
        nrAparitii = 0;
        sons = NULL;
    }
};

Trie T[NR_CELLS];
int root, size;

void initTrie()
{
    root = 0;
    size = root + 1;
}

void insert( char *s )
{
    int node = root;

    for ( ; *s; s++ )
    {
        int ch = *s - 'a';

        if ( !T[node].sons )
        {
            T[node].sons = new int[SIGMA];
            memset( T[node].sons, 0, sizeof( T[node].sons ) );
        }

        if ( !T[node].sons[ch] )
        {
            T[node].sons[ch] = size++;
            T[node].nrSons++;
        }

        node = T[node].sons[ch];
    }

    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';

        assert( T[node].sons[ch] != 0 );

        node = T[node].sons[ch];
        stiva[ ++top ] = node;
    }

    T[node].nrAparitii--;

    while ( T[node].nrAparitii == 0 && T[node].nrSons == 0 && node != root )
    {
        s--;

        if ( T[node].sons != NULL )
        {
            delete T[node].sons;
            T[node].sons = NULL;
        }

        node = stiva[ --top ];
        T[node].sons[*s - 'a'] = 0;
        T[node].nrSons--;
    }
}

int count( char *s )
{
    int node = root;

    for ( ; *s; ++s )
    {
        int ch = *s - 'a';

        if ( T[node].sons != NULL && T[node].sons[ch] != 0 )
            node = T[node].sons[ch];
        else
            break;
    }

    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';

        if ( T[node].sons != NULL && T[node].sons[ch] != 0 )
        {
            sol++;
            node = T[node].sons[ch];
        }
        else
            break;
    }

    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();

    return 0;
}