From 6d320b0386aa4d7c6bfe2d6fce3d68e227752bed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=B6rnquist?= Date: Tue, 19 Feb 2019 22:27:43 +0100 Subject: Further C++ improvements, maybe doesn't segfault now. --- trie.h | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 133 insertions(+), 2 deletions(-) (limited to 'trie.h') diff --git a/trie.h b/trie.h index 4613694e..4e01e837 100644 --- a/trie.h +++ b/trie.h @@ -3,6 +3,9 @@ #include +#include +#include + template struct trie_node { char c; @@ -23,9 +26,9 @@ struct trie { trie () : root (new trie_node ('\0')) { } - int push_back (const char* key, const T&); + int push (const char* key, T* item); - T& operator[] ( const char* key ); + T* operator[] ( const char* key ); bool empty () { return this->root->child == NULL; } }; @@ -33,4 +36,132 @@ struct trie { 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 */ -- cgit v1.2.3