Cod sursa(job #1485786)

Utilizator cernat.catallinFMI Cernat Catalin Stefan cernat.catallin Data 12 septembrie 2015 22:55:33
Problema Trie Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.54 kb
#include <fstream>
#include <algorithm>
#include <string>
#include <stack>
using namespace std;

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

class Trie {
private:
    struct Node {
        int nr_children, words_end;
        Node *children[26];

        Node() : nr_children(0), words_end(0), children{nullptr} {}
        ~Node() {
            // for (int i = 0; i < 26; ++i)
            //     if (children[i] != nullptr)
            //         delete children[i];
        }
    };

    Node *root;

public:
    Trie() : root(new Node) {}
    ~Trie() {
        // if (root != nullptr)
        //     delete root;
    }

    void add(const string &word) {
        Node *curr = root;
        for (unsigned int i = 0; i < word.size(); ++i) {
            if (curr->children[word[i] - 'a'] == nullptr) {
                curr->children[word[i] - 'a'] = new Node;
                ++curr->nr_children;
            }
            curr = curr->children[word[i] - 'a'];
        }
        ++curr->words_end;
    }

    void remove(const string &word) {
        remove_(root, word.c_str());
    }


    int apparitions(const string &word) {
        Node *curr = root;
        for (unsigned int i = 0; i < word.size(); ++i)
            if (curr->children[word[i] - 'a'] == nullptr)
                return 0;
            else
                curr = curr->children[word[i] - 'a'];
        return curr->words_end;
    }

    int longest_prefix(const string &word) {
        Node *curr = root;
        int len = 0;
        for (unsigned i = 0; i < word.size(); ++i)
            if (curr->children[word[i] - 'a'] != nullptr) {
                curr = curr->children[word[i] - 'a'];
                ++len;
            } else
                break;
        return len;
    }

private:
    bool remove_(Node *curr, const char *s) {
        if (*s == 0)
            --curr->words_end;
        else {
            if (remove_(curr->children[*s - 'a'], s + 1)) {
                --curr->nr_children;
                curr->children[*s - 'a'] = nullptr;
            }
        }

        if (curr->words_end == 0 && curr->nr_children == 0 && curr != root) {
            delete curr;
            return true;
        }
        return false;
    }
};

int main() {
    int op;
    string word;
    Trie trie;

    while (in >> op) {
        in >> word;

        if (op == 0)
            trie.add(word);
        else if (op == 1)
            trie.remove(word);
        else if (op == 2)
            out << trie.apparitions(word) << '\n';
        else
            out << trie.longest_prefix(word) << '\n';
    }

    return 0;
}