Cod sursa(job #2919686)

Utilizator geezusIancur de Hunedoara geezus Data 18 august 2022 18:09:17
Problema Trie Scor 55
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.7 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;

/*                    Represents a node in the trie data structure                    */
/* ================================================================================== */
struct TrieNode
{
    int EndOfWord, Common;
    char Letter;
    TrieNode* Next[26];

    TrieNode() { Common = 1; }
    TrieNode(char ch) { Letter = ch; Common = 1; }
};

void AddWord(TrieNode* node, string word, int wordIndex)
{
    if(wordIndex == word.length())
    {
        node->EndOfWord++;
        return;
    }

    int index = word[wordIndex] - 'a';
    if(node->Next[index] == nullptr)
        node->Next[index] = new TrieNode(index + 'a');
    else
        node->Next[index]->Common++;
    AddWord(node->Next[index], word, ++wordIndex);
}

bool TryGetNode(TrieNode* node, string word, int wordIndex, TrieNode& outNode)
{
    if(wordIndex == word.length())
    {
        outNode = (*node);
        return true;
    }

    int index = word[wordIndex] - 'a';
    if(node->Next[index] == nullptr)
        return false;
    return TryGetNode(node->Next[index], word, ++wordIndex, outNode);
}

void RemoveNode(TrieNode* node, string word, int wordIndex)
{
    if(wordIndex == word.length())
    {
        node->EndOfWord--;
        node->Common--;
        return;
    }

    int index = word[wordIndex] - 'a';
    if(node->Next[index] == nullptr)
        return;
    RemoveNode(node->Next[index], word, ++wordIndex);
    if(node->Next[index]->Common == 0)
    {
        delete node->Next[index];
        node->Next[index] = nullptr;
    }
}

/* ================================================================================== */


/*                      Draw an ugly representation of the trie                       */
/*                                           stolen from ttps://www.geeksforgeeks.org */
/* ================================================================================== */
void printNTree(TrieNode* x, int depth = 0, bool isLast = false)
{
    if (x == nullptr)
        return;

    for (int i = 1; i < depth; ++i)
        cout << " ";


    string amount = " x" + to_string(x->EndOfWord);
    string common = " c" + to_string(x->Common);
    amount += common;
    if (depth == 0)
        cout << x->Letter << amount << '\n';
    else
        cout << "+" << x->Letter << amount << '\n';

    int it = 0;
    for (int i = 0; i < 26; ++i, ++it)
        printNTree(x->Next[i], depth + 1, it == 25);
}

/* ================================================================================== */

int GetLongestCommon(TrieNode* node, string word, int wordIndex, int depth = 0)
{
    if(wordIndex == word.length())
        return depth;

    int index = word[wordIndex] - 'a';
    if(node->Next[index] == nullptr)
        return depth;
    return GetLongestCommon(node->Next[index], word, ++wordIndex, depth + 1);
}

int main()
{
    ifstream fin ("trie.in");
    ofstream fout ("trie.out");

    TrieNode* top = new TrieNode('*');
    int number;
    string word;
    while(fin >> number, fin >> word)
    {
        switch(number)
        {
            case 0:
            {
                AddWord(top, word, 0);
                break;
            }
            case 1:
            {
                RemoveNode(top, word, 0);
                break;
            }
            case 2:
            {
                TrieNode ans;
                bool found = TryGetNode(top, word, 0, ans);
                fout << (found ? ans.EndOfWord : 0) << "\n";
                break;
            }
            case 3:
            {
                //printNTree(top);
                fout << GetLongestCommon(top, word, 0) << "\n";
                break;
            }
        }
    }
    return 0;
}