COMPUTER ENGINEER

← BlogDATA STRUCTURES / ALGORITHMSPython example pack ↓

String algorithms · 39 / 53

KMP, prefix functions and the Z algorithm

Understand → trace → implement → justify

1 min reading · allow extra time for practice

Naive pattern search may repeat many comparisons after mismatches. KMP uses pi[i], the longest proper prefix of pattern[0:i+1] that is also its suffix. On mismatch set j=pi[j−1] without moving the text index backward.

Pattern aba has pi=[0,0,1]. After a complete match, falling back via pi finds overlaps. Z[i] measures the prefix match starting ati; a maintained match box enables linear construction. Pattern+separator+text methods need a genuinely distinct separator.

Algorithms match supplied symbols, not linguistic meaning. Unicode normalisation, empty patterns and byte versus code-point offsets need explicit contracts.

A worked trace

Text ababa and pattern aba match at0 and2. After the first match, j=1 retains the shareda.

Cost and assumptions

KMP O(n+m) time, O(m) space, plus z output positions.

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.

Python 3
def kmp(text, pattern):
    if not pattern: return list(range(len(text)+1))
    pi=[0]*len(pattern); j=0
    for i in range(1,len(pattern)):
        while j and pattern[i] != pattern[j]: j=pi[j-1]
        if pattern[i] == pattern[j]: j+=1
        pi[i]=j
    out=[]; j=0
    for i,c in enumerate(text):
        while j and c != pattern[j]: j=pi[j-1]
        if c == pattern[j]: j+=1
        if j == len(pattern): out.append(i-j+1); j=pi[j-1]
    return out
assert kmp("ababa","aba") == [0,2]

TEST YOUR UNDERSTANDING

Your turn

Must KMP move the text index backward on a mismatch?

Reveal the reasoning

No. It changes the matched pattern prefix while text progresses forward, supporting the linear bound.

Take it further

  1. Write down the input contract and the invariant before changing the example.
  2. Add empty, boundary, duplicate and adversarial cases where they are relevant. Compare with a simple oracle.
  3. 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 ↗
Solve the exercise before moving on.