Polynomial String Hashing
Tutorial Video
Text description (accessibility)
This video demonstrates the "Polynomial String Hashing" functional Rust example. Difficulty level: Fundamental. Key concepts covered: Functional Programming. Comparing strings character by character takes O(m) time. Key difference from OCaml: | Aspect | Rust | OCaml |
Tutorial
The Problem
Comparing strings character by character takes O(m) time. When you need to compare many substrings — checking if a string is a rotation of another, finding duplicate substrings, comparing all n^2 pairs of substrings — naive comparison becomes O(n^2 * m). Polynomial hashing reduces substring comparison to O(1) with O(n) preprocessing: compute prefix hashes, then any substring hash is (prefix[r] - prefix[l] * base^(r-l)) % mod. This enables O(n log n) string sorting, O(n) duplicate detection, and O(n log n) LCP (longest common prefix) binary search. It's the hash function behind rolling hash algorithms, string fingerprinting, and near-duplicate document detection.
🎯 Learning Outcomes
h[i] = h[i-1]*base + s[i] for O(1) substring hash queriesCode Example
#![allow(clippy::all)]
//! PlaceholderKey Differences
| Aspect | Rust | OCaml |
|---|---|---|
| Arithmetic type | u64 (64-bit unsigned) | int (63-bit signed) or Int64 |
| Underflow prevention | Add modulus^2 before subtract | Use absolute value or unsigned |
| Double hashing | Two PolyHash structs | Record with two hash arrays |
| Power precomputation | Vec<u64> with loop | Array.init or loop |
| Collision rate | 1/mod per hash | Same; 1/(mod1*mod2) for double |
| String access | .as_bytes()[i] | Char.code (String.get s i) |
OCaml Approach
OCaml uses Int64 or native int (63-bit on 64-bit systems) for modular arithmetic. The prefix hash array is Array.make (n+1) 0 and powers array is Array.make (n+1) 1. OCaml's lsl, land, and mod operators handle modular arithmetic. The get function is a simple pure function over the arrays. For double hashing, a record { h1: int array; h2: int array; pw1: int array; pw2: int array } keeps both hash functions bundled. OCaml's polymorphic comparison avoids the need for custom hash combination.
Full Source
#![allow(clippy::all)]
//! PlaceholderDeep Comparison
OCaml vs Rust: String Hashing Poly
Overview
See the example.rs and example.ml files for detailed implementations.
Key Differences
| Aspect | OCaml | Rust |
|---|---|---|
| Type system | Hindley-Milner | Ownership + traits |
| Memory | GC | Zero-cost abstractions |
| Mutability | Explicit ref | mut keyword |
| Error handling | Option/Result | Result<T, E> |
See README.md for detailed comparison.