ExamplesBy LevelBy TopicLearning Paths
821 Intermediate

Trie Autocomplete

Functional Programming

Tutorial Video

Text description (accessibility)

This video demonstrates the "Trie Autocomplete" functional Rust example. Difficulty level: Intermediate. Key concepts covered: Functional Programming. Autocomplete and prefix search are fundamental to user interfaces: search bars, IDE completion, spell checkers, and IP routing tables all need to answer "what words start with this prefix?" efficiently. Key difference from OCaml: | Aspect | Rust | OCaml |

Tutorial

The Problem

Autocomplete and prefix search are fundamental to user interfaces: search bars, IDE completion, spell checkers, and IP routing tables all need to answer "what words start with this prefix?" efficiently. A hash map of all words answers exact lookups in O(1) but cannot answer prefix queries. A trie (prefix tree) organizes strings by shared prefixes, enabling prefix queries in O(m) time where m is the prefix length — independent of how many words are stored. This also makes insertion, deletion, and "does any word start with X?" all O(m). Tries power the autocomplete in Google Search, the routing table lookup in routers, and the dictionary in word games.

🎯 Learning Outcomes

  • • Build a trie where each node maps characters to children and marks word endings
  • • Implement insert in O(m) by traversing/creating nodes character by character
  • • Implement prefix search by traversing to the prefix endpoint then collecting all completions via DFS
  • • Understand memory tradeoffs: tries use more memory than hash maps but enable prefix operations
  • • Recognize compressed tries (patricia/radix tries) as space optimization for sparse tries
  • Code Example

    #![allow(clippy::all)]
    //! Placeholder

    Key Differences

    AspectRustOCaml
    Node storageHashMap<char, TrieNode>Hashtbl or Map.Make(Char).t
    InsertionMutable traversal with entry()Mutable Hashtbl or immutable path copy
    Completions DFSRecursive with &mut Vec<String>Accumulator list or Buffer
    MemoryEach node heap-allocatedGC-managed, similar cost
    Sorted outputExtra sort stepMap gives sorted iteration free
    End markerbool fieldbool field or unit option

    OCaml Approach

    OCaml represents trie nodes as { children: (char * node) list; is_end: bool } or with a Hashtbl. Functional insertion creates a new node path, relying on structural sharing for efficiency. With mutable Hashtbl, insertion mutates like Rust's approach. OCaml's Map.Make(Char) creates a balanced BST per node for sorted child iteration — convenient for alphabetical autocomplete results. The DFS for completions uses continuation-passing or an accumulator list. OCaml's algebraic types make is_end a natural bool field.

    Full Source

    #![allow(clippy::all)]
    //! Placeholder

    Deep Comparison

    OCaml vs Rust: Trie Autocomplete

    Overview

    See the example.rs and example.ml files for detailed implementations.

    Key Differences

    AspectOCamlRust
    Type systemHindley-MilnerOwnership + traits
    MemoryGCZero-cost abstractions
    MutabilityExplicit refmut keyword
    Error handlingOption/ResultResult<T, E>

    See README.md for detailed comparison.

    Exercises

  • Implement delete(word) that removes a word while preserving words that share its prefix.
  • Add a frequency count per word and implement autocomplete returning the top-k most frequent completions.
  • Implement fuzzy search: return all words within Levenshtein distance 1 from a query.
  • Build a compressed radix trie (patricia trie) that merges single-child chains into single edges.
  • Measure memory usage of trie vs. sorted Vec<String> + binary search for a dictionary of 100k words.
  • Open Source Repos