Pagini recente » Cod sursa (job #2386933) | Cod sursa (job #2885059) | Cod sursa (job #1035811) | Cod sursa (job #1030106) | Cod sursa (job #2778681)
#include <fstream>
#include <list>
using namespace std;
#define ALPHABET_SIZE 26
#define map(c) c - 'a'
struct TrieNode {
TrieNode *children[ALPHABET_SIZE];
// de cate ori e folosit nodul curent pentru un cuvant
size_t app;
// marcheaza de cate ori nodul curent e sfarsit pentru un anumit cuvant
size_t endCount;
TrieNode() : app(0), endCount(0) {
for (int i = 0; i < ALPHABET_SIZE; i++)
children[i] = NULL;
}
};
struct Trie {
TrieNode *root;
Trie() : root(new TrieNode()) {}
void addWord(string &word) {
TrieNode *it = root;
string::iterator letter;
it->app++;
for (letter = word.begin(); letter != word.end(); letter++) {
if (it->children[map(*letter)] == NULL)
it->children[map(*letter)] = new TrieNode();
it = it->children[map(*letter)];
it->app++;
}
it->endCount++;
}
void erase(string &word) {
TrieNode *it = root;
string::iterator letter;
list<TrieNode *> garbage;
it->app--;
for (letter = word.begin(); letter != word.end(); letter++) {
TrieNode *parent = it;
it = it->children[map(*letter)];
it->app--;
if (it->app == 0) {
parent->children[map(*letter)] = NULL;
garbage.push_back(it);
}
}
it->endCount--;
while (!garbage.empty()) {
delete garbage.front();
garbage.pop_front();
}
}
size_t matchesOf(string &word) {
TrieNode *it = root;
string::iterator letter;
for (letter = word.begin(); letter != word.end(); letter++) {
if (it->children[map(*letter)] == NULL)
return 0;
it = it->children[map(*letter)];
}
return it->endCount;
}
size_t longestPrefixSizeOf(string &word) {
TrieNode *it = root;
string::iterator letter;
size_t pathLength = 0;
for (letter = word.begin(); letter != word.end(); letter++) {
if (it->children[map(*letter)] == NULL)
return pathLength;
it = it->children[map(*letter)];
++pathLength;
}
return pathLength;
}
~Trie() {
TrieNode *it = root;
list<TrieNode *> q;
q.push_back(it);
while (!q.empty()) {
it = q.front();
q.pop_front();
for (size_t i = 0; i < 26; i++) {
if (it->children[i])
q.push_back(it->children[i]);
}
delete it;
}
}
};
void solve(ifstream &in, ofstream &out) {
Trie *trie = new Trie();
int code;
string word;
while (true) {
// valoare care nu trebuie sa apara in input
code = 4;
in >> code;
if (code != 4) {
in >> word;
if (code == 0)
trie->addWord(word);
else if (code == 1)
trie->erase(word);
else if (code == 2)
out << trie->matchesOf(word) << '\n';
else if (code == 3)
out << trie->longestPrefixSizeOf(word) << '\n';
} else {
break;
}
}
delete trie;
}
int main(void) {
ifstream in("trie.in");
ofstream out("trie.out");
solve(in, out);
in.close();
out.close();
return 0;
}