#ifndef TRIE_H #define TRIE_H #include #include #include template struct trie_node { char c; T* value = NULL; trie_node* next = nullptr; trie_node* child = nullptr; trie_node (char c) : c(c) { }; trie_node (char c, trie_node* next, trie_node* child); }; template std::ostream& operator<<(std::ostream&, trie_node* node); template struct trie { trie_node* root; trie () : root (new trie_node ('\0')) { } int push (const char* key, T* item); T* operator[] ( const char* key ); bool empty () { return this->root->child == NULL; } }; template std::ostream& operator<<(std::ostream&, trie* trie); template trie_node::trie_node (char c, trie_node* next, trie_node* child) { this->c = c; this->next = next; this->child = child; } template int trie::push (const char* key, T* item) { trie_node *cur, *last; last = this->root; cur = last->child; // TODO subkey is never collected char* subkey = static_cast(malloc(strlen(key))); strcpy (subkey, key); while (true) { if (cur == NULL) { /* Build direct LL for remaining subkey */ for (char* c = subkey; c[0] != '\0'; c++) { // NEW(TRIE_NODE(TYPE), t, *c); auto t = new trie_node(*c); last->child = t; last = t; } // TODO fix resolve // last->value = RESOLVE(TYPE)(last->value, val); last->value = item; return 0; } else if (cur->c == subkey[0]) { /* This node belongs to the key, * Decend further */ last = cur; cur = cur->child; subkey++; } else if (subkey[0] == '\0') { /* Key finished */ // TODO fix resolve // last->value = RESOLVE(TYPE)(last->value, val); last->value = item; return 0; } else if (cur->next != NULL) { /* This node was not part of the set, but it's sibling might */ cur = cur->next; /* `last` not set since we aren't moving down */ } else { /* No node on self level was part of the set, create a new__ * sibling and follow down that parse */ // NEW(TRIE_NODE(TYPE), t, *subkey); auto t = new trie_node(*subkey); cur->next = t; last = cur; cur = t; } } } template T* trie::operator[] (const char* key) { trie_node* n = this->root->child; // TODO subkey is never collected char* subkey = static_cast(malloc(strlen(key))); strcpy (subkey, key); while (n != NULL) { if (subkey[1] == '\0') { return n->value; } else if (subkey[0] == n->c) { n = n->child; subkey++; } else { n = n->next; } } // ERR("Position not found"); // return 0; return nullptr; } template std::ostream& operator<<(std::ostream& o, trie_node* node) { #if 0 va_list ap; va_start(ap, buf); int argc = va_arg(ap, int); int depth = argc >= 1 ? va_arg(ap, int) : 0; va_end(ap); int seek = 0; #endif // TODO figure out depth int depth = 1; trie_node* n = node; if (n == NULL) { o << std::endl; } while (n != NULL) { o << '|'; for (int i = 0; i < depth; i++) o << ' '; o << (n->c == '\0' ? '0' : n->c); if (n->value != NULL) { o << n->value << std::endl; } if (n->child != NULL) { o << std::endl; o << n->child; // depth + 1 } n = n->next; } return o; } template std::ostream& operator<<(std::ostream& o, trie* trie) { o << "Trie: " << trie << " {\n"; o << trie->root->child; o << "}"; return o; } #endif /* TRIE_H */