Cod sursa(job #1005419)

Utilizator nimeniaPaul Grigoras nimenia Data 5 octombrie 2013 00:59:54
Problema Trie Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 3.85 kb
#include <iostream>
#include <fstream>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdlib>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <utility>
#include <string>
#include <vector>

using namespace std;

typedef vector<int> vi;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef map<string, int> msi;
typedef long long ll;
typedef unsigned long long ull;

typedef vector<int>::iterator vit;
typedef vector<ii>::iterator viit;
typedef vector<string>::iterator vst;

#define REP(i, n) for (int i = 0; i < n; ++i)
#define FOR(i, a, b) for (int i = a; i < b; ++i)
#define FORD(i, a, b) for (int i = a-1; i >= b; --i)
#define MP make_pair
#define PB push_back
#define ALL(x) (x).begin(), x.end()
#define SIZE(x) (int)(x).size()
#define FOREACH(it, c) for (__typeof(c.begin()) it = c.begin(); it != c.end(); ++it)
#define INF 1023456789
#define DEBUG(x) cerr << #x << ": " << x << endl;
#define ERR(...) fprintf(stderr, __VA_ARGS__);

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

class TrieNode {

    TrieNode* children[30];

public:
    int count;
    int nchildren;

    TrieNode() {
        count = 0;
        nchildren = 0;
        for (int i = 0; i < 30; i++)
            children[i] = NULL;
    }

    TrieNode* getChild(char c) {
        return this->children[c - 'a'];
    }

    void setChild(char c, TrieNode* node) {
        this->children[c - 'a'] = node;
        if (node == NULL) {
            nchildren--;
        } else {
            nchildren++;
        }
    }

    int nChildren() {
        return nchildren;
    }

};

class Trie {

    TrieNode* root;

public:
    Trie() {
        root = new TrieNode();
    }

    void add(string s) {
        TrieNode* node = root;
        for (int i = 0; i < s.length(); i++) {
            TrieNode *nxt = node->getChild(s[i]);
            if (nxt == NULL) {
                nxt = new TrieNode();
                node->setChild(s[i], nxt);
            }
            node = nxt;
            if (i == s.length() - 1)
            	node->count++;
        }
    }

    int get(string s) {
        TrieNode* node = root;
        for (int i = 0; i < s.length(); i++) {
            TrieNode *nxt = node->getChild(s[i]);
            if (nxt != NULL) {
                node = nxt;
                if (i == s.length() - 1)
                    return node->count;
            } else {
                break;
            }
        }
        return 0;
    }

    int lpm(string s) {
        TrieNode* node = root;
        int i = 0;
        for (; i < s.length(); i++) {
            TrieNode *nxt = node->getChild(s[i]);
            if (nxt == NULL)
                break;
            node = nxt;
        }
        return i;
    }

    void del(string s) {
      del_rec(s, root, 0);
    }

    TrieNode* del_rec(string s, TrieNode* node, int pos) {
        if (pos == s.size() && node->count > 0) {
        		node->count--;
        } else {
            TrieNode* nxt = node->getChild(s[pos]);
            if (nxt == NULL) {
                return node;
            }
            TrieNode* delNode = del_rec(s, nxt, pos + 1);
            node->setChild(s[pos], delNode);
        }
        if (node->count == 0 && node->nChildren() == 0) {
            return NULL;
        }
        return node;
    }
};

int main() {
    int op;
    string w;

    Trie* trie = new Trie();

    while (!f.eof()) {
        f >> op >> w;
        if (op == 0) {
            trie->add(w);
        } else if (op == 1) {
            trie->del(w);
        } else if (op == 2) {
            g << trie->get(w) << endl;
        } else if (op == 3) {
            g << trie->lpm(w) << endl;
        }
    }
}