C/C++ Arena

Step 6 of 6

Challenge: a trie for autocomplete

A trie (from retrieval, often said "try") stores strings character by character. Each node has up to 26 children, one per letter, and a flag marking where a complete word ends. Words that share a prefix share the path for it:

root
 └ c
   └ a
     ├ r *        "car"
     │ └ t *      "cart"
     └ t *        "cat"

So "which words start with ca?" only needs to walk two nodes, then look below, no matter how many other words the trie holds. Search boxes, spell checkers and network routers use tries.

#include <array>
#include <iostream>
#include <memory>
#include <string>

struct Node {
    std::array<std::unique_ptr<Node>, 26> next;   // one slot per letter
    bool end = false;
};

void insert(Node& root, const std::string& w) {
    Node* n = &root;
    for (char c : w) {
        auto& child = n->next[c - 'a'];
        if (!child) child = std::make_unique<Node>();
        n = child.get();
    }
    n->end = true;
}

void print_all(const Node& n, std::string& prefix) {
    if (n.end) std::cout << prefix << " ";
    for (int i = 0; i < 26; i++) {                 // 'a' to 'z': alphabetical order
        if (n.next[i]) {
            prefix.push_back(char('a' + i));
            print_all(*n.next[i], prefix);
            prefix.pop_back();                     // undo before trying the next letter
        }
    }
}

int main() {
    Node root;
    for (const char* w : {"cat", "car", "cart", "dog", "do"}) insert(root, w);
    std::string prefix;
    print_all(root, prefix);
    std::cout << "\n";
}
car cart cat do dog 

How it works

Your task's extras

Your turn: write class Trie for lowercase words:

Inserting the same word twice counts it once.

Previous: A binary heap by hand