Pagini recente » Cod sursa (job #757255) | Cod sursa (job #1873656) | Cod sursa (job #19835) | Cod sursa (job #2655257) | Cod sursa (job #771125)
Cod sursa(job #771125)
#include <cstdio>
#include <cstring>
class Trie {
public:
class Node {
public:
Node(bool word_stop = false);
int number_of_words();
void remove_son(char son);
Node* add_son(char son, bool mark_as_word = false);
Node* operator[](const char& son) const;
private:
int word_count_;
Node* sons_[26];
bool has_sons();
bool is_word();
void mark_as_word();
void de_mark();
};
Trie();
int length_of_longest_prefix(char* word);
int times_word_appears(char* word);
void add_word(char* word);
void remove_word(char* word);
private:
Node* root_;
int length_of_longest_prefix(char* word, Node* node, int level = -1);
int times_word_appears(char* word, Node* node);
void add_word(char* word, Node* node);
void remove_word(char* word, Node* node);
};
Trie::Node::Node(bool word_stop) {
this->word_count_ = word_stop ? 1 : 0;
}
Trie::Node* Trie::Node::operator[](const char& son) const {
char chr = son | 32;
if (chr >= 'a' && chr <= 'z') {
return this->sons_[chr - 'a'];
}
return NULL;
}
int Trie::Node::number_of_words() {
return this->word_count_;
}
Trie::Node* Trie::Node::add_son(char son, bool mark_as_word) {
char chr = son | 32;
int index;
if (chr < 'a' || chr > 'z') {
return NULL;
}
index = chr - 'a';
if (this->sons_[index] == NULL) {
this->sons_[index] = new Node(mark_as_word);
} else {
if (mark_as_word) {
this->sons_[index]->mark_as_word();
}
}
return this->sons_[index];
}
void Trie::Node::remove_son(char son) {
char chr = son | 32;
int index;
Node* the_son;
if (chr < 'a' || chr > 'z') {
return;
}
index = chr - 'a';
the_son = this->sons_[index];
if (the_son != NULL) {
the_son->de_mark();
if (!the_son->is_word() && !the_son->has_sons()) {
this->sons_[index] = NULL;
delete the_son;
}
}
}
bool Trie::Node::has_sons() {
for(int i = 0; i < 26; ++i) {
if (this->sons_[i] != NULL) {
return true;
}
}
return false;
}
bool Trie::Node::is_word() {
return this->word_count_ > 0;
}
void Trie::Node::mark_as_word() {
this->word_count_ += 1;
}
void Trie::Node::de_mark() {
this->word_count_ -= this->is_word() ? 1 : 0;
}
Trie::Trie() {
this->root_ = new Node();
}
void Trie::add_word(char* word) {
this->add_word(word, this->root_);
}
void Trie::add_word(char* word, Node* node) {
if (strlen(word) == 1) {
node->add_son(word[0], true);
return;
}
this->add_word(word + 1, node->add_son(word[0]));
}
void Trie::remove_word(char* word) {
this->remove_word(word, this->root_);
}
void Trie::remove_word(char* word, Node* node) {
if (node == NULL) {
return;
}
if (strlen(word) == 1) {
node->remove_son(word[0]);
return;
}
this->remove_word(word + 1, (*node)[word[0]]);
node->remove_son(word[0]);
}
int Trie::times_word_appears(char* word) {
return this->times_word_appears(word, this->root_);
}
int Trie::times_word_appears(char* word, Node* node) {
if (node == NULL) {
return 0;
}
if (strlen(word) == 1) {
return (*node)[word[0]]->number_of_words();
}
return this->times_word_appears(word + 1, (*node)[word[0]]);
}
int Trie::length_of_longest_prefix(char* word) {
return this->length_of_longest_prefix(word, this->root_);
}
int Trie::length_of_longest_prefix(char* word, Node* node, int level) {
if (node == NULL) {
return level;
}
return this->length_of_longest_prefix(word + 1, (*node)[word[0]], level + 1);
}
int main() {
Trie trie;
int op;
char str[23];
freopen("trie.in", "r", stdin);
freopen("trie.out", "w", stdout);
while(!feof(stdin)) {
memset(str, 0, 23 * sizeof(char));
scanf("%d %s", &op, str);
switch(op) {
case 0: {
trie.add_word(str);
break;
}
case 1: {
trie.remove_word(str);
break;
}
case 2: {
printf("%d\n", trie.times_word_appears(str));
break;
}
case 3: {
printf("%d\n", trie.length_of_longest_prefix(str));
break;
}
default: {
break;
}
}
}
fcloseall();
return 0;
}