Cod sursa(job #3178307)

Utilizator Mihai145Oprea Mihai Adrian Mihai145 Data 1 decembrie 2023 16:23:17
Problema Trie Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.65 kb
#include <fstream>
#include <string>

using namespace std;

ifstream cin("trie.in");
ofstream cout("trie.out");

const int SIGMA = 26;

// FW declarations
class Node;
Node *insert_trie(Node *node, const std::string &s, int position);
Node *delete_trie(Node *node, const std::string &s, int position);
int cnt_words(Node *node, const std::string &s, int position);
int lcp(Node *node, const std::string &s, int position);
void cleanup(Node *node);

class Node
{
private:
    Node *sons[SIGMA];
    int cnt_ap, cnt_w;

public:
    Node()
    {
        cnt_ap = cnt_w = 0;
        for (int i = 0; i < SIGMA; i++)
            sons[i] = nullptr;
    }

    friend Node *insert_trie(Node *node, const std::string &s, int position);
    friend Node *delete_trie(Node *node, const std::string &s, int position);
    friend int cnt_words(Node *node, const std::string &s, int position);
    friend int lcp(Node *node, const std::string &s, int position);
    friend void cleanup(Node *node);
};

Node *insert_trie(Node *node, const std::string &s, int position = 0)
{
    if (node == nullptr)
        node = new Node();

    node->cnt_ap++;

    if (position == (int)s.size())
        node->cnt_w++;
    else
        node->sons[s[position] - 'a'] = insert_trie(node->sons[s[position] - 'a'], s, position + 1);

    return node;
}

Node *delete_trie(Node *node, const std::string &s, int position = 0)
{
    node->cnt_ap--;

    if (position == (int)s.size())
        node->cnt_w--;
    else
        node->sons[s[position] - 'a'] = delete_trie(node->sons[s[position] - 'a'], s, position + 1);

    return node;
}

int cnt_words(Node *node, const std::string &s, int position = 0)
{
    if (node == nullptr)
        return 0;
    if (position == (int)s.size())
        return node->cnt_w;

    return cnt_words(node->sons[s[position] - 'a'], s, position + 1);
}

int lcp(Node *node, const std::string &s, int position = 0)
{
    if (node == nullptr || node->cnt_ap == 0)
        return position - 1;

    if (position == (int)s.size())
        return s.size();

    return lcp(node->sons[s[position] - 'a'], s, position + 1);
}

void cleanup(Node *node)
{
    if (node == nullptr)
        return;

    for (int i = 0; i < SIGMA; i++)
        cleanup(node->sons[i]);

    delete node;
}

int main()
{
    Node *root = nullptr;

    int command;
    string s;

    while (cin >> command >> s)
    {
        if (command == 0)
            root = insert_trie(root, s);
        else if (command == 1)
            root = delete_trie(root, s);
        else if (command == 2)
            cout << cnt_words(root, s) << '\n';
        else
            cout << lcp(root, s) << '\n';
    }

    // cleanup
    cleanup(root);

    return 0;
}