Cod sursa(job #1756213)

Utilizator killer301Ioan Andrei Nicolae killer301 Data 12 septembrie 2016 10:43:12
Problema Trie Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 3.21 kb
///Trie-Infoarena
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>

using namespace std;

const int NrCharacters = 50;
const int NMAX = 30;

struct TrieNode
{
    int NrWord;
    inline bool hasNoSons()
    {
        for(int i=0; i<26; i++)
            if((*this).sons[i] != NULL)
                return false;
        return true;
    }
    inline bool hasSons(int Exception)
    {
        for(int i=0; i<26; i++)
            if(i!=Exception && this->sons[i]!=NULL)
                if( (this->sons[i]->NrWord)>0 || (this->sons[i]->hasSons(-1))!=NULL )
                    return true;
        return false;
    }
    TrieNode *sons[NrCharacters];
};

TrieNode *root;

void AddToTrie(TrieNode *node, const char *str, int length, int CurrentPosition)
{
    if(length == CurrentPosition)
    {
        (*node).NrWord++;
    }
    else
    {
        int Next = str[CurrentPosition] - 'a';
        if((*node).sons[Next] == NULL)
            (*node).sons[Next] = new TrieNode();
        AddToTrie((*node).sons[Next], str, length, CurrentPosition+1);
    }
}

bool DeleteFromTrie(TrieNode *node, const char *str, int length, int CurrentPosition)
{
    if(length == CurrentPosition)
    {
        node -> NrWord --;
        if(node -> NrWord == 0)
        {
            delete node;
            return true;
        }
        return false;
    }
    int Next = str[CurrentPosition] - 'a';
    if(DeleteFromTrie(node -> sons[Next], str, length, CurrentPosition+1))
        node -> sons[Next] = 0;
    if(node -> NrWord == 0 && node -> hasNoSons() && node != root)
    {
        delete node;
        return true;
    }
    return false;
}

int Ans;

void NrWords(TrieNode *node, const char *str, int length, int CurrentPosition)
{
    if(length == CurrentPosition)
    {
        Ans = (*node).NrWord;
    }
    else
    {
        int Next = str[CurrentPosition] - 'a';
        if((*node).sons[Next] == NULL)
        {
            Ans = 0;
            return;
        }
        NrWords((*node).sons[Next], str, length, CurrentPosition+1);
    }
}

void Prefixlength(TrieNode *node, const char *str, int length, int CurrentPosition)
{
    if(length == CurrentPosition)
    {
        if((*node).hasSons(-1) || (*node).NrWord>0)
            Ans = length;
    }
    else
    {
        int Next = str[CurrentPosition] -  'a';
        if( (*node).hasSons(Next) || (*node).NrWord>0)Ans = CurrentPosition;
        if((*node).sons[Next] == NULL)return;
        Prefixlength((*node).sons[Next], str, length, CurrentPosition+1);
    }
}

int main()
{
    freopen("trie.in", "r", stdin);
    freopen("trie.out", "w", stdout);
    root = new TrieNode();
    int type;
    char *a;
    a = (char*) malloc(21);
    while(scanf("%d %s", &type, a)!=EOF)
    {
        int n = strlen(a);
        if(type == 0)AddToTrie(root, a, n, 0);
        else if(type == 1)DeleteFromTrie(root, a, n, 0);
        else if(type == 2)
        {
            NrWords(root, a, n, 0);
            cout << Ans << "\n";
        }
        else if(type == 3)
        {
            Prefixlength(root, a, n, 0);
            cout << Ans << "\n";
        }
    }
    return 0;
}