Cod sursa(job #1679461)

Utilizator killer301Ioan Andrei Nicolae killer301 Data 7 aprilie 2016 23:18:07
Problema Trie Scor 5
Compilator cpp Status done
Runda Arhiva educationala Marime 2.99 kb
///Trie-Infoarena
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>

using namespace std;

const int NrCharacters = 26;
const int NMAX = 20;

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]->sons[i])!=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);
    }
}

void DeleteFromTrie(TrieNode *node, const char *str, int length, int CurrentPosition)
{
    if(length == CurrentPosition)
    {
        (*node).nrWord--;
        if((*node).nrWord==0 && (*node).hasNoSons())
            delete node;
    }
    else
    {
        int Next = str[CurrentPosition] - 'a';
        DeleteFromTrie((*node).sons[Next], str, length, CurrentPosition+1);
        if((*node).hasNoSons() && node!=root)
            delete node;
    }
}

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