Worked examples — KMP algorithm — failure function, O(n+m) — full derivation
The scenario matrix
Every string the failure function can face falls into one of these case classes. The examples below hit every cell.
| # | Case class | What makes it special | Example |
|---|---|---|---|
| A | Generic pattern (mixed borders) | rises and falls, normal fallback chain | Ex 1 |
| B | All-identical characters aaaa |
climbs — maximal borders | Ex 2 |
| C | No border at all abcd |
stays everywhere — worst reuse | Ex 3 |
| D | Nested / chained borders | one mismatch falls back through several slots | Ex 4 |
| E | Degenerate inputs — length-1 pattern, empty pattern, empty text | ; and edges | Ex 5 |
| F | Overlapping matches | full match, then continue via not | Ex 6 |
| G | No match exists | text pointer marches, never reaches | Ex 7 |
| H | Amortized limit (adversarial) | the -killer input, proving linearity | Ex 8 |
| I | Real-world word problem | applied framing | Ex 9 |
| J | Exam twist — smallest period from | using for a different question | Ex 10 |
Example 1 — Generic pattern (Cell A)
Forecast: Guess: does reach before dropping? Where does it drop to ?
- : by definition (single char, no proper prefix). Why this step? Every build starts here — it is the base case of the recurrence.
- (
b):j=pi[0]=0;S[1]=b,S[0]=a, mismatch,j=0already → (Case 3). Why? No prefix ofabis also a suffix. - (
c):j=0;c≠a→ (Case 3). Why? Withj=0we compare the new charcto the very first chara; they differ and is already , so no prefix ofabcis a suffix — border length stays . - (
a):j=pi[2]=0;S[3]=a,S[0]=amatch →j=1, (Case 1). Why? The prefixanow reappears as a suffix ofabca. - (
b):j=pi[3]=1;S[4]=b,S[1]=bmatch →j=2, (Case 1). Why? Borderabgrew from borderaby one matching char. - (
c):j=2;S[5]=c,S[2]=cmatch →j=3, (Case 1). Why? The border wasab(length 2); the new charcequalsS[2]=c, so the border extends by one toabc(length 3) — Case 1 firing a third time in a row. - (
d):j=3;S[6]=d,S[3]=amismatch →j=pi[2]=0(Case 2);d≠a→ (Case 3). Why?dbreaks every border; we fall to the bottom.
Answer: .
Verify: abcabc has longest proper prefix=suffix abc (length 3) ✓; adding d kills all borders ✓.
Example 2 — All-identical characters (Cell B)
Forecast: Will be or something smaller?
- : .
- :
j=0;a==a→j=1, (Case 1). Why? Prefixa= suffixaofaa. Proper (length 1 < 2). ✓ - :
j=pi[1]=1;S[2]=a,S[1]=amatch →j=2, (Case 1). Why? The previous border wasa(length 1); the new char equalsS[1]=a, so the border extends toaa(length 2). - :
j=pi[2]=2;S[3]=a,S[2]=amatch →j=3, (Case 1). Why? Borderaa(length 2) extends by the matching charS[2]=atoaaa(length 3); still proper because .
Answer: .
Verify: For aaaa, the longest proper prefix that is a suffix is aaa (length ) — never , because proper forbids the whole string. This is exactly why we insist on proper in the definition: allowing the whole string would give everywhere and the fallback j=pi[j-1] would never shrink , causing an infinite loop.
Example 3 — No border anywhere (Cell C)
Forecast: What does look like when nothing ever repeats?
- .
- :
j=pi[0]=0;S[1]=b,S[0]=a,b≠a→ (Case 3). Why?jis already and the new charbdiffers from the first chara, so no prefix ofabis a suffix — border stays . - :
j=pi[1]=0;S[2]=c,S[0]=a,c≠a→ (Case 3). Why? Same situation:cdiffers from the first chara, soabchas no prefix=suffix. - :
j=pi[2]=0;S[3]=d,S[0]=a,d≠a→ (Case 3). Why?ddiffers froma;abcdhas no repeated character, so no border can exist.
Answer: .
Verify: No character repeats, so no prefix can equal any suffix — is all zeros. On a mismatch, matching such a pattern behaves exactly like naive (nothing to reuse), yet still because never rewinds. See Borders and Periods of Strings for the border-free case.
Example 4 — Nested border chain (Cell D)
Forecast: At the last char, how many times does the while loop fire?
- .
Why? Base case — a single char
ahas no proper prefix. - (
a):j=pi[0]=0;a==a→ (Case 1). Why? The new charaequals the first charS[0]=a, soaahas bordera(length 1). - (
b):j=pi[1]=1;S[2]=b,S[1]=amismatch →j=pi[0]=0(Case 2);b≠a→ (Case 3). Why? The borderacannot extend (b≠a), so we fall back to ; still no match, so border length is . - (
a):j=pi[2]=0;a==a→ (Case 1). Why? Withj=0, the new charaequalsS[0]=a, restarting a border of length 1 foraaba. - (
a):j=pi[3]=1;S[4]=a,S[1]=amatch → (Case 1). Why? Bordera(length 1) extends by the matching charS[1]=atoaa(length 2). - (
a):j=pi[4]=2;S[5]=a,S[2]=bmismatch →j=pi[1]=1(Case 2);S[5]=a,S[1]=amatch → (Case 1). Why the fallback? Border of length 2 couldn't extend (b≠a), so we asked "what is the longest border inside that border?" — — and tried again. This is the border chain walking down (Case 2). - (
b):j=pi[5]=2;S[6]=b,S[2]=bmatch → (Case 1). Why? Borderaa(length 2) extends by the matching charS[2]=btoaab(length 3).
Answer: .
Verify: aabaaab — longest proper prefix=suffix is aab (length 3): prefix aab = last three chars aab ✓. Step 6 fired the while once (Case 2) then matched (Case 1) — the chained fallback in action.
Example 5 — Degenerate inputs (Cell E)
Forecast: Can a single character have a border? How many matches does an empty pattern have?
- Length-1 pattern
x: by definition — a single char has no proper prefix (the only prefix is the whole thing, which is forbidden). Why? Proper prefix must be strictly shorter; nothing shorter than length 1 except the empty string, which gives border length 0. - Empty pattern (): the build loop
for i=1..m-1never runs; is the empty array. In matching,j==misj==0— a match is reported at every position (the empty string occurs everywhere). Guard this in code with an explicitif m==0to avoid readingpi[m-1]=pi[-1]. Why care? Contest judges love empty-input edge cases; forgetting the guard gives out-of-range reads. - Empty text (): the match loop
for i=0..n-1never runs, so stays . Result: zero matches for any non-empty pattern — correct, since nothing can occur in nothing. (If too, conventions differ; most define the empty pattern to match once, at position 0.) Why mention it? It is the mirror image of the empty pattern — the degenerate case on the text side, and it must not crash: an empty loop simply produces an empty match list.
Answer: ; empty pattern → matches everywhere; empty text → no matches (for non-empty ).
Verify: For x, longest proper prefix=suffix length is ✓. Searching any pattern in an empty text yields ✓.
Example 6 — Overlapping matches (Cell F)
Forecast: How many matches — 2 or 3? (Naive-reset thinking says 2.)
First, and .
| before | action | after | ||
|---|---|---|---|---|
| 0 | a | 0 | match → j=1 |
1 |
| 1 | a | 1 | match → j=2=m, report , j=pi[1]=1 |
1 |
| 2 | a | 1 | match → j=2=m, report , j=1 |
1 |
| 3 | a | 1 | match → j=2=m, report , j=1 |
1 |
Why this step (the j=pi[m-1] on match)? After reporting, we keep the overlap a (length ) instead of throwing it away, so the next a completes the next overlapping match. Resetting j=0 would drop the overlap and miss matches.
Answer: matches at indices — three overlapping aa.
Verify: aaaa contains aa starting at 0,1,2 ✓. Resetting j=0 would have missed indices 1 and 2 — this is why a full match continues via , not .
Example 7 — No match exists (Cell G)
Forecast: Does ever reach ?
, .
| before | action | after | ||
|---|---|---|---|---|
| 0 | a | 0 | a==a → j=1 |
1 |
| 1 | b | 1 | b==b → j=2 |
2 |
| 2 | a | 2 | P[2]=x≠a, j=pi[1]=0; a==a → j=1 |
1 |
| 3 | b | 1 | b==b → j=2 |
2 |
| 4 | a | 2 | x≠a, j=0; a==a → j=1 |
1 |
| 5 | b | 1 | b==b → j=2 |
2 |
Why does still march forward on every mismatch? Because the reused prefix P[0..π[j-1]-1] is already known equal to the text — re-reading it is wasted work. tops out at , never .
Answer: no matches; never reaches .
Verify: abx does not occur in ababab ✓ (no x). Total text reads = 6, one per char — linear even with zero matches.
Example 8 — Adversarial amortized limit (Cell H)
Forecast: How many inner-while steps fire in total across the whole run?
, , .
The interesting positions: while the text feeds a, climbs . Let us count the amortized budget instead of every row:
- Total
jincreases (at most one+1per text char). Why? Theif T[i]==P[j]line runs once per . - Total
whiledecreases total increases , since always and eachwhilestep drops by . Why? behaves like a bank account: deposits , so withdrawals . - Therefore inner steps across the entire scan are , not .
Running it, the single match is aaab: the b is at index 7, and aaab ends there, starting at .
Answer: one match at index ; total inner-while steps → runtime , not . See Amortized Analysis.
Verify: aaaaaaab[4:8] aaab ✓; and no earlier start works because a match needs the b.
Example 9 — Real-world word problem (Cell I)
Forecast: Overlaps again — 1 hit or 2?
, .
| before | action | after | ||
|---|---|---|---|---|
| 0 | A | 0 | match → j=1 |
1 |
| 1 | T | 1 | match → j=2 |
2 |
| 2 | A | 2 | match → j=3=m, report , j=pi[2]=1 |
1 |
| 3 | T | 1 | match → j=2 |
2 |
| 4 | A | 2 | match → j=3=m, report , j=1 |
1 |
| 5 | T | 1 | match → j=2 |
2 |
Why report 0 and 2? The overlap A (length ) is preserved after each hit, so the next TA completes the following motif. A gene aligner must catch overlaps — biology does not care that they share a base.
Answer: motif ATA starts at indices .
Verify: ATATAT[0:3]=ATA ✓, ATATAT[2:5]=ATA ✓, no start at index 4 (only AT remains).
Example 10 — Exam twist: smallest period from (Cell J)
Forecast: Is the answer 3? Or 9 (no repetition)?
- Build the last value. By the same climb as Ex 1,
abcabcabchas (longest proper prefix=suffix isabcabc). Why ? The first 6 charsabcabcequal the last 6abcabc. - Apply the period formula. . Why does this work? A border of length means the string, shifted right by , still lines up with itself on the overlapping region. A shift that leaves the string aligned with itself is precisely a period. So the smallest such shift, , is the smallest period candidate. See Borders and Periods of Strings.
- Check the divisibility condition . Here and , and , so . This is what upgrades from "a shift that aligns" to "the string is exactly full copies of the block
abc." If did not divide (say the string wereabcabca, , , , but ), the string would be only partially periodic — the last block is a fragment — and the smallest full period would be itself. Why check it at all? Because the question asks for a period that tiles completely; without the block does not tile, so the answer must fall back to .
Answer: smallest period (abc repeated three times), and since this is a genuine full period.
Verify: , ✓; abc×3 = abcabcabc ✓. Counter-check: abcabca gives but , so it is not fully periodic ✓.
Recall Which cell was hardest?
The nested chain (Ex 4) and the overlap trap (Ex 6). If you can do those two cold, the rest are routine.
Which example proves linearity? ::: Example 8 — the adversarial aaaaaaab amortized count.
Which formula did the exam twist use? ::: smallest full period when it divides .