Algorithm Search⌘K

Proofs: Boyer-Moore algorithm

These are the human proofs of Boyer-Moore algorithm, at full length.

Boyer-Moore outputs exactly the valid shifts full

This proof shows: correctness, termination.

Claim. For a text T[0…n−1]T[0 \ldots n-1] and a pattern P[0…m−1]P[0 \ldots m-1], BOYER-MOORE(T,P)(T, P) stops and outputs exactly the shifts ss, 0≤s≤n−m0 \le s \le n - m, with T[s…s+m−1]=PT[s \ldots s+m-1] = P, in increasing order.

We take as given the two tables: λ(c)\lambda(c) is the largest kk with P[k]=cP[k] = c, or −1-1; and gs[j]\mathrm{gs}[j], for 0≤j<m0 \le j < m, is the smallest d≥1d \ge 1 such that (G1) P[i−d]=P[i]P[i-d] = P[i] for all ii with j<i<mj < i < m and i≥di \ge d, and (G2) j−d<0j - d < 0 or P[j−d]≠P[j]P[j-d] \ne P[j]. That lines L13 to L23 compute these values is the procedure described on the page of the good-suffix rule. For m=0m = 0, line L2 outputs every shift, which is correct, so let m≥1m \ge 1.

Lemma 1 (the period). gs[0]\mathrm{gs}[0] is the smallest period pp of PP, the smallest d≥1d \ge 1 with P[i−d]=P[i]P[i - d] = P[i] for all d≤i<md \le i < m.

Proof. For j=0j = 0, (G2) always holds because 0−d<00 - d < 0, and (G1) asks P[i−d]=P[i]P[i-d] = P[i] for max⁡(1,d)≤i<m\max(1, d) \le i < m, which is the same as d≤i<md \le i < m since d≥1d \ge 1. □\square

Lemma 2 (safe shifts). Let ss be a shift tested by the loop of line L5, and let Δ\Delta be the amount added to ss by line L11 or L12. Then Δ≥1\Delta \ge 1, and no shift s′s' with s<s′<s+Δs < s' < s + \Delta is valid.

Proof. If the window matched (line L11), Δ=p≥1\Delta = p \ge 1. A valid shift s′=s+ds' = s + d with 1≤d<p1 \le d < p would give P[i−d]=T[s+i]=P[i]P[i - d] = T[s + i] = P[i] for all d≤i<md \le i < m, since both PP at ss and PP at s+ds + d equal the text there; so dd would be a period smaller than pp, a contradiction.

Otherwise, lines L7 and L8 stopped at j≥0j \ge 0 with P[i]=T[s+i]P[i] = T[s+i] for j<i<mj < i < m and P[j]≠T[s+j]=cP[j] \ne T[s+j] = c, and Δ=max⁡(gs[j],j−λ(c))≥gs[j]≥1\Delta = \max(\mathrm{gs}[j], j - \lambda(c)) \ge \mathrm{gs}[j] \ge 1. Let s′=s+ds' = s + d be valid with 1≤d<Δ1 \le d < \Delta, so T[s+d+k]=P[k]T[s + d + k] = P[k] for 0≤k<m0 \le k < m, and s+d+m≤ns + d + m \le n.

  • If d<gs[j]d < \mathrm{gs}[j], then (G1) or (G2) fails for dd. For j<i<mj < i < m with i≥di \ge d, the text position s+is + i lies in both windows, so P[i−d]=T[s+i]=P[i]P[i - d] = T[s+i] = P[i]: (G1) holds. So (G2) fails: j−d≥0j - d \ge 0 and P[j−d]=P[j]P[j - d] = P[j]. But the text position s+js + j is in the window at s′s', so P[j−d]=T[s+j]=c≠P[j]P[j - d] = T[s + j] = c \ne P[j], a contradiction.
  • If d<j−λ(c)d < j - \lambda(c), then j−d>λ(c)≥−1j - d > \lambda(c) \ge -1, so 0≤j−d<j<m0 \le j - d < j < m and P[j−d]=T[s+j]=cP[j-d] = T[s+j] = c. That is an occurrence of cc at the position j−d>λ(c)j - d > \lambda(c), which contradicts the definition of λ\lambda.

In both cases s′s' is not valid. □\square

Theorem. The claim holds.

Proof. We show the invariant: at line L5, the output is the increasing list of the valid shifts smaller than ss. It holds for s=0s = 0. In one iteration, the window at ss is tested by lines L6 to L8, which stop with j<0j < 0 exactly when P[i]=T[s+i]P[i] = T[s+i] for all 0≤i<m0 \le i < m; then ss is output, and it is larger than every earlier output. By Lemma 2, no shift strictly between ss and s+Δs + \Delta is valid, so the invariant holds for s+Δs + \Delta. Each iteration increases ss by at least 1, so the loop stops after at most n−m+2n - m + 2 iterations, with s>n−ms > n - m; the inner loop runs at most mm times. At that point every valid shift, being at most n−mn - m, is smaller than ss, so the output is complete. ■\blacksquare

Back to Boyer-Moore algorithm