Keep the text from the previous page and change the pattern from ain to zebra. There is no z anywhere in the rain in spain stays mainly in the plain, so no alignment gets past its first comparison. The lab reports 39 comparisons over 39 alignments, at exactly 1 per alignment, against a bound of 5 × 39 = 195.
Theorem · Naive matching on a text avoiding the pattern's first characterIf no character of t equals p[0], the naive matcher makes exactly n − m + 1 comparisons and reports no match.
Each alignment begins by comparing t[i] with p[0]. By hypothesis these differ, so the inner loop stops with k = 0 after one comparison, and the alignment reports nothing.
There are n − m + 1 alignments and each contributes exactly 1, so the total is n − m + 1. No alignment reaches k = m, so no match is reported, which is correct because a match would require t[i] to equal p[0].
□
Theorem · Knuth–Morris–Pratt on the same textIf no character of t equals p[0], KMP makes exactly n comparisons.
KMP maintains k, the number of pattern characters currently matched, starting at 0. Its fallback loop runs only while k > 0.
Suppose k = 0 on entering the step for text position i. The fallback loop is skipped, one comparison of t[i] against p[0] is made, and by hypothesis it fails, so k stays 0. By induction k is 0 at every position, so exactly one comparison happens at each of the n positions and the total is n.
□
Subtract: n − (n − m + 1) = m − 1. On this input that is 4, and the panel reports 39 against 43. The margin does not depend on the text at all, only on the length of the pattern, so lengthening zebra to zebraic widens it to 6 without touching either algorithm.
Example · The same reversal at six text lengthsThe growth table repeats the text and the two columns stay apart in the same direction. Naive reads 39, 82, 125, 168, 211, 254 as n runs 43, 86, 129, 172, 215, 258, and KMP reads 43, 86, 129, 172, 215, 258 — which is n itself, in every row. The difference is 4 in every row, because it is m − 1 and m never moved.
What the guarantee is actually for
Switch the preset to the one built to reach the bound and read the same two columns: naive 100, KMP 44, on a text of 24 characters. KMP is not better on average here or worse on average there; it is the algorithm whose count cannot exceed 2n whatever is typed, and naive matching is the algorithm whose count cannot exceed m(n − m + 1). At n = 24 and m = 5 those two ceilings are 48 and 100, and the measured numbers sit under each.
So the honest summary of the pair of experiments is: the measured counts reverse between two texts, and the bounds do not. Whichever direction you want to argue, the evidence for it is a proof and the numbers are illustrations.
Horspool, which wins here by a wider margin and promises nothing
The third column reports 14. Horspool compares the window from the right and then shifts by the last occurrence of the text character sitting under the window's final position, which for a letter absent from the pattern is the full m. So it reads roughly one character in five and finishes in 14 comparisons where naive needs 39.
That is the largest saving on the page and the one with the least behind it. Horspool's worst case is m(n − m + 1) comparisons, the same as naive's, and the sibling lesson “The Text Where Nothing Is Skipped” is a 30-character text on which it makes 130 comparisons and naive makes 26.
Put the three side by side and the ordering changes twice in this course with no algorithm changing at all. That is the point: the ranking is a property of the input, and the only statements that survive every input are the bounds, which do not rank them at all.