ID photo of Ciro Santilli taken in 2013 right eyeCiro Santilli OurBigBook logoOurBigBook.com  Sponsor 中国独裁统治 China Dictatorship 新疆改造中心、六四事件、法轮功、郝海东、709大抓捕、2015巴拿马文件 邓家贵、低端人口、西藏骚乱
cpp/trie.cpp
#include <cassert>
#include <set>
#include <string>
#include <unordered_map>
#include <vector>
#include <iostream>

class Trie {
public:
    void push(char c, Trie* child, bool terminal) {
        children[c] = { child, terminal };
        ordered_keys.insert(c);
    }

    std::vector<std::string> findPrefix(std::string pref) {
        std::vector<std::string> ret;
        auto cur = this;
        bool terminal;
        for (const char c : pref) {
            auto child = children.find(c);
            if (child == children.end())
                break;
            cur = child->second.first;
            terminal = child->second.second;
        }
        std::vector<std::tuple<Trie*,bool,std::string>> todo = {{cur, terminal, pref}};
        while (!todo.empty()) {
            auto [cur, terminal, curPref] = todo.back();
            todo.pop_back();
            if (terminal) {
                ret.push_back(curPref);
            }
            for (auto it = cur->ordered_keys.rbegin(); it != cur->ordered_keys.rend(); ++it) {
                auto c = *it;
                auto child = cur->children[c];
                todo.emplace_back(child.first, child.second, curPref + c);
            }
        }
        return ret;
    }
private:
    std::unordered_map<char,std::pair<Trie*,bool>> children;
    std::set<char> ordered_keys;
};
// TODO convert to typedef. Needs something else to forward declare Trie*,
// not sure if possible and how.
//typedef std::unordered_map<char,std::pair<Trie*,bool>> Trie;

int main() {
    // The wikipedia example nodes numbered breadth first.
    Trie tries[11];
    // t
    tries[0].push('t', &tries[1], false);
    // A
    tries[0].push('A', &tries[2], true);
    // i
    tries[0].push('i', &tries[3], false);
    // to
    tries[1].push('o', &tries[4], true);
    // te
    tries[1].push('e', &tries[5], false);
    // in
    tries[3].push('n', &tries[6], true);
    // tea
    tries[5].push('a', &tries[7], true);
    // ted
    tries[5].push('d', &tries[8], true);
    // ten
    tries[5].push('n', &tries[9], true);
    // inn
    tries[6].push('n', &tries[10], true);

    // 
    assert(
        tries[0].findPrefix("t") ==
        (std::vector<std::string>{
            "tea",
            "ted",
            "ten",
            "to",
        })
    );
}