#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLEN 21
#define TRIESZ 26
struct trie_node {
int count;
int children;
struct trie_node *child[TRIESZ];
};
struct trie_node *new_trie_node()
{
struct trie_node *p = malloc(sizeof(struct trie_node));
p->count = 0;
p->children = 0;
for (int i = 0; i < TRIESZ; i++)
p->child[i] = NULL;
return p;
}
void delete_trie(struct trie_node *p)
{
if (p == NULL)
return;
for (int i = 0; i < TRIESZ; i++)
delete_trie(p->child[i]);
free(p);
}
void add_word_helper(struct trie_node *p, char *s, int len, int level)
{
if (level == len) {
p->count++;
return;
}
int idx = s[level] - 'a';
if (p->child[idx] == NULL) {
p->child[idx] = new_trie_node();
p->children++;
}
add_word_helper(p->child[idx], s, len, level + 1);
}
void add_word(struct trie_node *p, char *s, int len)
{
add_word_helper(p, s, len, 0);
}
void delete_word_helper(struct trie_node *p, char *s, int len, int level)
{
if (level == len) {
p->count--;
return;
}
int idx = s[level] - 'a';
if (level == len - 1 &&
p->child[idx]->children == 0 &&
p->child[idx]->count == 1) {
free(p->child[idx]);
p->child[idx] = NULL;
p->children--;
return;
}
delete_word_helper(p->child[idx], s, len, level + 1);
}
void delete_word(struct trie_node *p, char *s, int len)
{
delete_word_helper(p, s, len, 0);
}
int get_count_helper(struct trie_node *p, char *s, int len, int level)
{
if (p == NULL)
return 0;
if (level == len)
return p->count;
int idx = s[level] - 'a';
return get_count_helper(p->child[idx], s, len, level + 1);
}
int get_count(struct trie_node *p, char *s, int len)
{
return get_count_helper(p, s, len, 0);
}
int get_prefix_len_helper(struct trie_node *p, char *s, int len, int level)
{
if (p == NULL)
return level - 1;
int idx = s[level] - 'a';
return get_prefix_len_helper(p->child[idx], s, len, level + 1);
}
int get_prefix_len(struct trie_node *p, char *s, int len)
{
return get_prefix_len_helper(p, s, len, 0);
}
int main()
{
freopen("trie.in", "r", stdin);
freopen("trie.out", "w", stdout);
// do operations
int op, len, ret;
char word[MAXLEN];
struct trie_node *p = new_trie_node();
while (scanf("%d%s", &op, word) == 2) {
len = strlen(word);
switch (op) {
case 0:
add_word(p, word, len);
break;
case 1:
delete_word(p, word, len);
break;
case 2:
ret = get_count(p, word, len);
printf("%d\n", ret);
break;
case 3:
ret = get_prefix_len(p, word, len);
printf("%d\n", ret);
break;
}
}
delete_trie(p);
return 0;
}