Pagini recente » Cod sursa (job #2020432) | Cod sursa (job #2782597) | Cod sursa (job #326917) | Cod sursa (job #1594015) | Cod sursa (job #1526703)
// (a..z) --> Nodes
// Terminating character
// ab aba
// a -> b (null)
// a -> b (1) -> a (1)
//
// a -> b -> a (null)
#include <string>
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
constexpr int alpha = 'z' - 'a' + 1;
struct Node {
vector<Node*> cs;
vector<int> count;
Node() {
cs = vector<Node*>(alpha, nullptr);
count = vector<int>(alpha, 0);
}
Node* get_node(char c) {
return cs[c - 'a'];
}
void set_node(char c, Node *n) {
cs[c - 'a'] = n;
}
int get_count(char c) {
return count[c - 'a'];
}
void set_count(char c, int v) {
count[c - 'a'] = v;
}
void inc_count(char c) {
count[c - 'a']++;
}
int dec_count(char c) {
return --count[c - 'a'];
}
int count_all_set(char c) {
return count_if(
count.begin(),
count.end(),
[](int a) {return a > 0;});
}
int children_count() {
return count_if(
cs.begin(),
cs.end(),
[](Node* n) {return n != nullptr;});
}
};
class Trie {
public:
Node* root;
Trie() {
root = new Node();
}
void insert(const string& w) {
Node* crt = root;
int i = 0;
for (; i < w.size(); i++) {
char c = w[i];
if (crt->get_node(c) == nullptr)
crt->set_node(c, new Node());
crt = crt->get_node(c);
}
crt->inc_count(w[i]);
}
void del(const string& w) {
del_rec(w, root, 0);
}
string lcp(const string& w) {
Node *crt = root;
int i = 0;
string l;
for (i; i < w.size(); i++) {
char c = w[i];
if (crt->get_node(c) != nullptr) {
crt = crt->get_node(c);
l += c;
//std::cout << "Update best" << std::endl;
}
}
return l;
}
int count(const string& w) {
Node* crt = root;
int i;
for (int i = 0; i < w.size(); i++) {
crt = crt->get_node(w[i]);
if (crt == nullptr)
return 0;
}
return crt->get_count(w[i]);
}
Node* del_rec(const string& w, Node* n, int pos) {
if (n == nullptr)
return nullptr;
char c = w[pos];
//std::cout << "del_rec " << c << " " << n->get_count(c) << std::endl;
if (pos == w.size()) {
if (n->dec_count(c) > 0)
return n;
n->set_node(c, nullptr);
} else
n->set_node(c, del_rec(w, n->get_node(c), pos + 1));
//std::cout << c << " " << n->children_count() << std::endl;
if (n->children_count() == 0) {
//std::cout << "Deleting node" << std::endl;
delete n;
return nullptr;
}
return n;
}
};
int main () {
ifstream f{"trie.in"};
ofstream g{"trie.out"};
int a;
string s;
Trie t;
while (f >> a >> s) {
switch (a) {
case 0:
t.insert(s);
break;
case 1:
t.del(s);
break;
case 2:
g << t.count(s) << endl;
break;
case 3:
g << t.lcp(s).size() << endl;
break;
}
}
}