Pagini recente » Cod sursa (job #366538) | Cod sursa (job #2718343) | Cod sursa (job #2222432) | Cod sursa (job #2739062) | Cod sursa (job #2485130)
#include <fstream>
using namespace std;
#pragma pack(1)
class trie {
public:
trie() : crawler(nullptr) {
for (auto& i : root.sons)
i = nullptr;
root.parent = nullptr;
}
void add(const char* target) {
crawler = begin();
offset = 0;
for (char letter = *target; letter; letter = *(target + ++offset)) {
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(const char* target) {
crawler = begin();
for (char letter = *target; letter; letter = *(target + ++offset)) {
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(const char* target) {
crawler = begin();
for (char letter = *target; letter; letter = *(target + ++offset)) {
if (crawler->sons[normalize(letter)] == nullptr)
return 0;
crawler = crawler->sons[normalize(letter)];
}
return crawler->occurences;
}
int get_closest_match_length(const char* target) {
crawler = begin();
int retval = 0;
for (char letter = *target; letter; letter = *(target + ++offset)) {
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;
static int8_t offset;
inline 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, * crawler;
node* begin() { return &root; }
void clean_node(node* target) {
for (auto i : target->sons)
if (i != nullptr)
clean_node(i);
delete target;
}
};
ifstream fin("trie.in");
ofstream fout("trie.out");
int main() {
int query;
trie h;
char* str = new char[21];
for (; 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;
}
}
}
delete[] str;
return 0;
}