HOW we derive the shift. We mismatched at pattern index j with text char c.
We want to move P right so that the rightmost c in P aligns under position s+j.
If last(c)<j: that occurrence is to the left of j, so shift = j−last(c)≥1.
If last(c)=−1: no c in P, shift the whole pattern past it: j−(−1)=j+1.
If last(c)>j: aligning it would move the pattern backwards — illegal. We clamp to a minimum shift of 1.
Why does Boyer-Moore compare the pattern right-to-left?
So a mismatch reveals a matched suffix, enabling large skips via the good-suffix rule and aligning the bad text char with its rightmost copy in P.
Define last(c) (last-occurrence function).
The largest index i with P[i]=c, or −1 if c∈/P.
Bad-character shift formula at mismatch index j with text char c?
max(1,j−last(c)).
Why the max(1,⋅) in bad-character shift?
When last(c)≥j the raw value is ≤0 (backward/zero shift) → infinite loop; clamp to at least 1.
What is a "good suffix"?
The already-matched suffix P[j+1…m−1] when mismatch occurs at index j.
Two cases of the good-suffix rule?
(1) Align another internal occurrence of the good suffix whose preceding char differs from P[j]; (2) align a prefix of P equal to a suffix of the good suffix.
Final BM shift on mismatch?
max(bad-char shift,good-suffix shift).
Why is taking the max of the two shifts safe?
Each rule is an independent valid lower bound on a safe jump; the larger of two safe jumps is still safe.
Best-case and worst-case time of basic BM search?
Best O(n/m) (sublinear), worst O(nm); Galil rule makes it O(n).
Preprocessing cost?
O(m+∣Σ∣) for bad char, O(m) for good suffix.
Recall Feynman: explain to a 12-year-old
Imagine matching a word stamp onto a long sentence. Instead of checking letters left to right, you check the stamp from its last letter backward. The moment a letter doesn't match, you ask two questions: "Where else in my stamp does this wrong letter appear?" (slide so they line up) and "The part that did match — does it appear somewhere earlier in my stamp?" (slide so that lines up too). You then jump by the bigger of the two jumps. Because you sometimes skip whole chunks of the sentence without even looking, it's super fast.
Boyer-Moore ka core idea ye hai ki naive matching ki tarah pattern ko ek-ek step slide mat karo, aur comparison right se left karo — yaani pattern ke last character se shuru karke peeche ki taraf. Jab koi mismatch aata hai, tab hum do smart rules use karke ek bada jump maar dete hain.
Pehla rule bad character hai: jis text character ne mismatch kiya (use c bolte hain), uska pattern ke andar rightmost occurrence dhoondo aur pattern ko itna slide karo ki wo occurrence us text position ke neeche aa jaye. Agar c pattern me hai hi nahi, to poora pattern us position se aage chhalang maar jata hai — isi wajah se BM kabhi-kabhi text ke saare characters padhta bhi nahi, matlab sublinear speed. Bas dhyan rakho: shift kabhi ≤0 na ho, isliye max(1,…) lagana zaroori hai, warna infinite loop.
Doosra rule good suffix hai: mismatch se pehle jo part match ho chuka tha (the matched suffix), wo "achha" hai — use waste mat karo. Pattern ko aise slide karo ki ya to ussi suffix ka ek aur copy pattern ke andar align ho jaye (lekin uske pehle wala character alag hona chahiye, warna same mismatch dobara), ya phir pattern ka koi prefix us suffix ke end se match kar jaye. Dono rules se jo shift aata hai, unme se bada (max) lo — wahi safe aur fast hota hai.
Yaad rakhne ka tareeka: "Right se padho, Bad aur Good me se Bigger jump lo." Yeh algorithm bade alphabets (jaise English text) par KMP se bhi tez chalta hai practical me, isliye grep jaise tools isi family ko use karte hain.