Knuth–Morris–Pratt (KMP)
String matching in O(n + m): no text character is read twice; after a mismatch, the prefix function says how far the pattern moves.
After a mismatch the naive method moves the pattern by one and compares from the start again. But we already know
that the last q text characters matched P[0..q−1]. So:
- Time:
O(n + m) - Space:
O(m) - CLRS, section 32.4
- Horowitz–Sahni, chapter 2
The pattern ababa occurs three times in bacbababababa, at shifts 4, 6 and 8; after the first match KMP keeps the overlap instead of starting over.
def kmp_match(T, P):n, m = len(T), len(P)pi = prefix_function(P)matches = []q = 0 # how many characters of P match the text ending hereshift = 0 # where P sits under T, for the picturefor i in range(n):while q > 0 and P[q] != T[i]:q = pi[q - 1]if P[q] == T[i]:q = q + 1if q == m:matches.append(i - m + 1)q = pi[q - 1]shift = i - q + 1return matchesdef prefix_function(P):pi = [0] * len(P)k = 0for q in range(1, len(P)):while k > 0 and P[k] != P[q]:k = pi[k - 1]if P[k] == P[q]:k = k + 1pi[q] = kreturn pi
Start
0123456789101112
bacbababababa
ababa
pi—
matches—
Local variables
T'bacbababababa'
P'ababa'
Orange = changed in this step
Call stack
- kmp_match()line 1
Step 1 of 115
Explanation
The idea
After a mismatch the naive method moves the pattern by one and compares from the start again. But we already know
that the last q text characters matched P[0..q−1]. So:
- if
T[i]matchesP[q],qgrows by one; - if not, set
qtoπ[q − 1](the longest border of the matched part) and try again; the text is not re-read; - if
q = m, the pattern is found; go on withq = π[m − 1]so overlapping occurrences are found too.
Cost
i only moves forward and each fall-back shrinks q; so the whole job is O(n), plus O(m) to build π.
What to watch in the trace
- The
ipointer only moves forward over the text; the pattern is drawn at its current shift and its filled cells have matched.