Cod sursa(job #904466)

Utilizator toranagahVlad Badelita toranagah Data 4 martie 2013 14:48:54
Problema Trie Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.69 kb
#include <algorithm>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

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

const int MAX_N = 100100;
const int ALPHA_SIZE = 26;

class Trie {
public:
    Trie();
    int add_entry(const string&, int entry_count = 1);
    int remove_entry(const string&);
    int look_up(const string&);
    int max_prefix(const string&);
private:
    int get_node(int, char);
    void set_node(int, int, char);
    struct TrieNode {
        TrieNode();
        int times_found, num_contained;;
        int node_location[ALPHA_SIZE];
    };
    vector<TrieNode> tree;
};


int main() {
    Trie dictionary;
    int operation;
    string word;
    while (fin >> operation && fin >> word) {
        switch (operation) {
        case 0:
            dictionary.add_entry(word);
            break;
        case 1:
            dictionary.remove_entry(word);
            break;
        case 2:
            fout << dictionary.look_up(word) << '\n';
            break;
        case 3:
            fout << dictionary.max_prefix(word) << '\n';
            break;
        default:
            cerr << "ERROR! Operation undetermined" << endl;
        }
    }
    return 0;
}

Trie::Trie() {
    tree.push_back(TrieNode());
}

Trie::TrieNode::TrieNode() {
    times_found = num_contained = 0;
    for (int i = 0; i < ALPHA_SIZE; ++i) {
        node_location[i] = -1;
    }
}

int Trie::add_entry(const string& entry, int entry_count) {
    int current_node = 0;
    for (unsigned int i = 0; i < entry.size(); ++i) {
        int next_node = get_node(current_node, entry[i]);
        if (next_node == -1) {
            if (entry_count <= 0) return 0;
            set_node(current_node, tree.size(), entry[i]);
            current_node = tree.size();
            tree.push_back(TrieNode());
        } else {
            current_node = next_node;
        }
        tree[current_node].num_contained += entry_count;
    }
    return (tree[current_node].times_found += entry_count);
}

int Trie::remove_entry(const string& entry) {
    return add_entry(entry, -1);
}

int Trie::look_up(const string &entry) {
    return add_entry(entry, 0);
}

int Trie::max_prefix(const string &entry) {
    int current_node = 0;
    for (unsigned int i = 0; i < entry.size(); ++i) {
        int next_node = get_node(current_node, entry[i]);
        if (next_node == -1 || tree[next_node].num_contained <= 0) {
            return i;
        }
        current_node = next_node;
    }
    return entry.size();
}

inline int Trie::get_node(int node, char ch) {
    return tree[node].node_location[ch - 'a'];
}

inline void Trie::set_node(int node, int next, char ch) {
    tree[node].node_location[ch - 'a'] = next;
}