String algorithms · 40 / 53
Rabin–Karp and Aho–Corasick
Understand → trace → implement → justify
1 min reading · allow extra time for practiceRabin–Karp compares fixed-length windows with a rolling hash: remove the old character contribution, shift by the base, add the new character and reduce modulo. Equal hashes are not proof of equality. Direct verification restores deterministic correctness but may increase worst-case cost; double hashing reduces rather than eliminates collision risk.
Aho–Corasick stores many patterns in a trie and follows failure links to the longest viable suffix. Output links report suffix patterns that would otherwise be missed. BFS constructs failure states in dependency order.
Pattern lengths, alphabet representation and output count shape costs. Text filtering also requires normalisation and boundary policies; the algorithm does not determine linguistic semantics.
A worked trace
With he,she,hers, reading she reports both she and its suffixhe through failure/output links.
Cost and assumptions
Verified Rabin–Karp worst O(nm); Aho with suitable transitions costs total pattern length+n+output.
Executable example
Run with Python 3. Assertions check a small example; they do not constitute a general correctness proof. Some advanced examples are explicitly small models or reference oracles, not full production implementations.
def rolling_hashes(text, width, base=257, mod=1000000007):
if not 1 <= width <= len(text): return []
high=pow(base,width-1,mod); h=0
for c in text[:width]: h=(h*base+ord(c))%mod
result=[h]
for i in range(width,len(text)):
h=((h-ord(text[i-width])*high)*base+ord(text[i]))%mod
result.append(h)
return result
assert len(rolling_hashes("ababa",3)) == 3TEST YOUR UNDERSTANDING
Your turn
What type of algorithm results if hash matches are not verified?
Reveal the reasoning
A Monte Carlo approach with possible false matches from collisions. State the probabilistic correctness contract.
Take it further
- Write down the input contract and the invariant before changing the example.
- Add empty, boundary, duplicate and adversarial cases where they are relevant. Compare with a simple oracle.
- Derive the cost under the stated model; measure several input sizes and explain discrepancies.
Primary reading & lecture notes
Original explanations in this course; these references provide proofs and further reading. Source links may cover the broader module.
Princeton · Algorithms, Sedgewick & Wayne ↗