Cod sursa(job #2940622)

Utilizator BuzatuCalinBuzatu Calin BuzatuCalin Data 15 noiembrie 2022 22:44:47
Problema Trie Scor 5
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.92 kb
#include <iostream>
#include <fstream>
#include <unordered_map>
using namespace std;
int n;
char s[1001];
ifstream fin("trie.in");
ofstream fout("trie.out");
struct Trie
{
    bool endOfWord;
    int aparitii;
    unordered_map <char, int > fr;
    unordered_map <char, Trie* > map;
};
Trie* createNewNode()
{
    Trie* node = new Trie;
    node -> endOfWord = false;
    node -> aparitii = 0;
    return node;
}
void insert(Trie *&root, char *str)
{
    if (root == nullptr)
    {
        root = createNewNode();
    }
    Trie *curr = root;
    while (*str)
    {
        //cout << str << ' ' << curr -> fr[*str] << '\n';
        curr -> fr[*str] ++;
        if (curr -> map.find(*str) == curr -> map.end())
        {
            curr -> map[*str] = createNewNode();
        }
        if (curr -> map[*str] == nullptr)
        {
            curr -> map[*str] = createNewNode();
        }
        curr = curr -> map[*str];
        str ++;
        
    }
    if (curr == nullptr )
    {
        curr = createNewNode();
        curr -> map[*str]= createNewNode();
    }
    
    curr -> aparitii ++;
    curr -> fr[*str]++;
    curr -> endOfWord = true;
}
bool hasChildren(Trie *curr)
{
    if (curr == nullptr)
    {
        return false;
    }
    for (auto it: curr -> map)
    {
        if (it.second != nullptr)
        {
            return true;
        }
    }
    return false;
}
int search(Trie *curr, char *str)
{
    if (curr == nullptr)
    {
        return 0;
    }
    while (*str)
    {
        //cout << *str << '\n';
        if (curr == nullptr || curr -> map[*str] == nullptr) 
        {
            return 0;
        }
        curr = curr -> map[*str];
        str ++;
    }
    return curr -> aparitii;
}
bool delete_node(Trie *&curr, char *str)
{
    if (curr == nullptr)
    {
        return false; 
    }
    if (*str)
    {

        if (curr != nullptr)
        {
            curr -> fr[*str] --;
        }
        if (curr != nullptr && curr -> map[*str] != nullptr && curr -> endOfWord == false )
        {
            //cout << curr -> map[*str] << ' ' << *str << '\n';
            if (curr -> map.find(*str) != curr -> map.end() && delete_node(curr -> map[*str], str + 1) )
            {
                if (!hasChildren(curr))
                {
                    delete curr;
                    curr = nullptr;
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
        else
        {
            return false;
        }
    }
    if (*str == '\0' && curr ->endOfWord == true)
    {
        if (!hasChildren(curr))
        {
            delete curr;
            curr = nullptr;
            return true;
        }
        else
        {
            curr -> endOfWord = false;
            return false;
        }
    }
    return false;
}
int longest_prefix(Trie *curr, char *str)
{
    if (curr == nullptr)
    {
        return 0;
    }
    int maxim = 0, lung = 1;
    while (*str)
    {
        //cout << *str << '\n';
        if (curr == nullptr || curr -> map[*str] == nullptr)
        {
            return maxim;
        }
        if (curr -> fr[*str] >= 1)
        {
            maxim = lung;
        }
        curr = curr -> map[*str];
        lung ++;
        str ++;
    }
    return maxim;
}
int main()
{
    Trie* root = nullptr;
    int op;
    int n; 
    while (fin >> op >> s)
    {   
        //cout << op << s << '\n';
        if (op == 0)
        {
            insert(root, s);
        }
        else if (op == 1)
        {
            delete_node(root, s);
        }
        else if (op == 2)
        {
            fout << search(root, s) << '\n';
        }
        else if (op == 3)
        {
            fout << longest_prefix(root, s) << '\n';
        }
    }
}