Cod sursa(job #1588260)

Utilizator sebii_cSebastian Claici sebii_c Data 2 februarie 2016 22:08:37
Problema Trie Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.21 kb
#include <fstream>
#include <iostream>
#include <memory>
#include <unordered_map>

using namespace std;

template<class T, class...Args>
std::unique_ptr<T> make_unique(Args&&... args) {
    std::unique_ptr<T> ret(new T(std::forward<Args>(args)...));
    return ret;
}

class Trie {
    int cnt;
    unordered_map<char, unique_ptr<Trie>> children;

public:
    void add(const string& s) {
	add(s.begin(), s.end());
    }

    void del(const string& s) {
	del(s.begin(), s.end());
    }

    int count(const string& s) {
	return count(s.begin(), s.end());
    }

    int prefix(const string& s) {
	return prefix(s.begin(), s.end());
    }
    
    void add(string::const_iterator s, string::const_iterator e) {
	if (s == e) {
	    cnt++;
	} else {
	    if (children.count(*s)) {
		children[*s]->add(std::next(s), e);
	    } else {
		children.emplace(*s, make_unique<Trie>());
		children[*s]->add(std::next(s), e);
	    }
	}
    }

    void del(string::const_iterator s, string::const_iterator e) {
	if (s == e) {
	    --cnt;
	} else {
	    if (!children.count(*s)) {
		return;
	    } else {
		children[*s]->del(std::next(s), e);
		if (children[*s]->cnt == 0 && children[*s]->children.empty()) {
		    children.erase(*s);
		}
	    }
	}
    }

    int count(string::const_iterator s, string::const_iterator e) {
	if (s == e) {
	    return cnt;
	} else {
	    if (!children.count(*s)) {
		return 0;
	    } else {
		return children[*s]->count(std::next(s), e);
	    }
	}
    }

    int prefix(string::const_iterator s, string::const_iterator e) {
	if (s == e) {
	    return 0;
	} else {
	    if (!children.count(*s)) {
		return 0;
	    } else {
		return 1 + children[*s]->prefix(std::next(s), e);
	    }
	}
    }
};

int main() {
    ifstream fin("trie.in");
    ofstream fout("trie.out");
    
    Trie root;
    
    int type; string word;
    while (fin >> type >> word) {
	switch (type) {
	case 0:
	    root.add(word);
	    break;
	case 1:
	    root.del(word);
	    break;
	case 2:
	    fout << root.count(word) << endl;
	    break;
	case 3:
	    fout << root.prefix(word) << endl;
	    break;
	default:
	    break;
	}
    }
    
    return 0;
}