Pagini recente » Cod sursa (job #687718) | Cod sursa (job #2423968) | Cod sursa (job #2297291) | Cod sursa (job #1159196) | Cod sursa (job #2485137)
#include <fstream>
#include <vector>
#include <string>
using namespace std;
#pragma pack(1)
class trie {
public:
trie() {
for (auto& i : root.sons)
i = nullptr;
root.parent = nullptr;
}
void add(std::string* target) {
node* crawler = this->begin();
for (auto letter : *target) {
if (crawler->sons[normalize(letter)] == nullptr)
++(crawler->forks),
crawler->sons[normalize(letter)] = new node(1 + crawler->level, normalize(letter)),
crawler->sons[normalize(letter)]->parent = crawler;
crawler = crawler->sons[normalize(letter)];
}
if (crawler->occurences++ == 0)
crawler->end_of_word = true;
}
void remove(std::string* target) {
node* crawler = this->begin();
for (auto letter : *target) {
if (crawler->sons[normalize(letter)] == nullptr)
return;
crawler = crawler->sons[normalize(letter)];
}
if (--crawler->occurences == 0) {
crawler->end_of_word = false;
node* next;
while (crawler->forks == 0 && !crawler->end_of_word && crawler != this->begin()) {
next = crawler->parent;
--next->forks;
next->sons[crawler->index] = nullptr;
delete crawler;
crawler = next;
}
}
}
int get_occurences(std::string* target) {
node* crawler = this->begin();
for (auto letter : *target) {
if (crawler->sons[normalize(letter)] == nullptr)
return 0;
crawler = crawler->sons[normalize(letter)];
}
return crawler->occurences;
}
int get_closest_match_length(std::string* target) {
node* crawler = this->begin();
int retval = 0;
for (auto letter : *target) {
if (crawler->sons[normalize(letter)] == nullptr)
return retval;
++retval;
crawler = crawler->sons[normalize(letter)];
}
return retval;
}
~trie() {
return;
for (auto i : root.sons)
if (i != nullptr)
clean_node(i);
}
private:
static const int start_of_alphabet = 'a';
static const int size_of_alphabet = 26;
int normalize(const char& target) {
return target - start_of_alphabet;
}
struct node {
node* sons[size_of_alphabet] = {};
node* parent;
int forks : 5, /// delete bit fields for other alphabets
level : 5,
index : 6,
occurences : 15,
end_of_word : 1;
node(int _level = 0, int letter = 0) : forks(0), occurences(0), end_of_word(false) {
index = letter;
level = _level;
}
} root;
node* begin() {
return &root;
}
void clean_node(node* target) {
for (auto i : target->sons)
if (i != nullptr)
clean_node(i);
delete target;
}
};
int main() {
ifstream fin("trie.in");
ofstream fout("trie.out");
int query;
trie h;
for (string str; fin >> query;) {
fin >> str;
switch (query) {
case 0: {
h.add(&str);
break;
}
case 1: {
h.remove(&str);
break;
}
case 2: {
fout << h.get_occurences(&str) << "\n";
break;
}
case 3: {
fout << h.get_closest_match_length(&str) << "\n";
break;
}
}
}
return 0;
}