#include #include #include #include #include #include template < typename Key > class Trie { public: typedef std::unique_ptr ptr; Trie(): children_() { } inline void add(std::forward_list path) { this->add(path, path.begin()); } inline void add(std::forward_list& path, typename std::forward_list::const_iterator curr) { if ( curr != path.end() ) { Trie::ptr& trie = this->children_[*curr]; if ( trie ) { trie->add(path, ++curr); } else { trie.reset(new Trie()); trie->add(path, ++curr); } } } inline Trie* resolve(std::forward_list path) const { return this->resolve(path, path.begin()); } inline Trie* resolve( std::forward_list& path, typename std::forward_list::const_iterator curr ) const { auto trie = this->children_.find(*curr); if ( trie != this->children_.end() ) { auto next = ++curr; if ( next == path.end() ) { return (*trie).second.get(); } else { return (*trie).second->resolve(path, next); } } else { return nullptr; } } protected: std::map children_; }; int main() { Trie test; test.add(std::forward_list{1, 2, 3}); test.add(std::forward_list{1, 2, 4}); test.add(std::forward_list{2, 1}); test.add(std::forward_list{2, 1, 1}); assert(test.resolve(std::forward_list{1, 2}) != nullptr); assert(test.resolve(std::forward_list{1, 2, 4}) != nullptr); assert(test.resolve(std::forward_list{3}) == nullptr); }