3.8.5 · D3 · HinglishString Algorithms

Worked examplesBoyer-Moore — bad character, good suffix heuristics

3,420 words16 min read↑ Read in English

3.8.5 · D3 · Coding › String Algorithms › Boyer-Moore — bad character, good suffix heuristics

Yeh hands-on companion note hai parent note ka. Wahan humne do rules banaye the; yahan hum unhe drive karte hain har us situation se jo ek real text mein aa sakti hai. Yeh page self-contained hai: har symbol jo yahan use hota hai, use pehle neeche (re)build kiya gaya hai.

Recall Teen numbers jo hamesha chahiye
  • ::: woh pattern index jahan mismatch hua (hum right to left compare karte hain, isliye se start hota hai).
  • ::: bad character — woh text character jo mismatch ke neeche baitha hai (yaad rakho woh alignment offset hai jo upar define kiya gaya hai).
  • ::: ke andar woh rightmost index jahan character appear karta hai, ya agar kabhi appear hi nahi karta.

Bad-character shift: . Good-suffix shift: (array bilkul neeche banaya gaya hai). Total shift: .


Do building blocks jo pehle chahiye

Kisi bhi example se pehle hum un do ideas ko define karna zaroori hai jinpar good-suffix rule tika hua hai: ek border, aur good-suffix shift array . Hum inhe yahan scratch se banate hain taaki is page par kuch bhi bahar se borrowed na ho.


Scenario matrix

Search ke dauran har mismatch ya full match neeche diye gaye algorithmic cases A–H mein se exactly ek mein fit hota hai. (Cases I aur J naye cases nahi hain — yeh woh contexts hain jisme wahi A–H logic exercise hota hai; hum examples ko inse sirf isliye tag karte hain taaki rules ko realistic pressure mein dikha sakein.)

Case Situation Shift kya decide karta hai Galat karo toh kya risk
A Bad char mein hai hi nahi () poora pattern aage slide: koi nahi — yeh aasaan bada jump hai
B Bad char ke left mein () yeh exist karna bhool jana → bahut slow
C Bad char ke right mein () formula ho jaata hai → clamp to 1 infinite loop / backward shift
D Mismatch bilkul pehle compare par () abhi tak koi matched suffix nahi, isliye chhota hai; bad char rules good suffix par zyada trust karna
E Good suffix internally reoccur karta hai (Case 1) us earlier copy ko align karo jiske preceding char alag ho aisa copy lena jiska same preceding char ho → repeat mismatch
F Sirf ka ek border = good suffix ka suffix (Case 2) us border ko align karo, shift Case 2 bhool jana → over-shift, match miss
G Full match mila ( neeche se chala jaata hai) se shift karo se shift karna kaam bekar karta hai; se shift overlaps skip kar sakta hai
H Degenerate pattern () worst case ; Galil rule fix karta hai yeh sochna ki BM hamesha fast hai

Neeche use hone wale context tags: I = real-world large-alphabet search (DNA), jahan Case A baar baar fire hota hai → sublinear; J = exam-style "do rules mein se kaun jeetataa hai?".


Example 1 — Case C phir Case A (context I: real-world DNA)

Step 1 — line up karo aur right-to-left padho (alignment (i)). ; text char hai . ko 0 se count karte hue: G C T T C T G C. Match, par jao. Yeh step kyun? BM right-to-left compare karta hai; ek match ek matched suffix chheel deta hai.

Step 2 — pehla mismatch pakdo (alignment (i)). ✓; ✓; vs mismatch. Toh , . Yeh step kyun? Pehli disagreement hi decision point hai.

Step 3 — yeh Case C hai (bad char right mein). in CCTTTTGC = index 7. Kyunki , naive illegal hai (backward). Clamp: . Yeh step kyun? Ek rightmost copy ko jo mismatch ke right mein ho align karna ko peeche kheench dega.

Step 4 — ek clean Case A (alignment (ii)). Yahan at . Right-to-left compare karo: ✓; ✓; ✓; vs mismatch at , . Character A CCTTTTGC mein absent hai, isliye aur — Case A jump, jin characters ko humne kabhi padha hi nahi unhe skip karte hue. Yeh step kyun? Case A aur Case C genuinely alag hain; dono ko apna-apna concrete text dena shift ko poori tarah reproducible rakhta hai.

Verify: Case C → . Case A → . Dono positive aur legal. ✓


Example 2 — Case B (bad char left mein)

Step 1 — bad character locate karo. . Kyun? Mismatch ke neeche ka text char bad-character rule drive karta hai.

Step 2 — compute karo. A B C A B mein sirf ek C hai index 2 par. Toh . Kyun? Hum ke andar ki rightmost copy chahte hain taaki use mismatch position ke neeche slide kar sakein.

Step 3 — formula apply karo. Case B. . Kyun? Ek leftward occurrence ek positive, legal shift deta hai — yahan sirf 1, chhota par valid.

Verify: . Index-2 C ko text position ke neeche align karna ko exactly right move karta hai. ✓


Example 3 — Case C (bad char right mein, clamp)

Step 1 — . ABCAB mein, A positions 0 aur 3 par appear karta hai; rightmost 3 hai. Kyun? Standard bad-character lookup.

Step 2 — se compare karo. Case C. Kyun? Rightmost A mismatch ke right mein hai, isliye naive formula deta hai.

Step 3 — clamp karo. . Kyun? ka shift ko left move karta hai, wahi region dobara-dobara padhte raho forever. guard isse rokta hai. Good-suffix rule usually yahan ek bada legal jump deta hai.

Verify: . Clamp ke bina milta → non-terminating loop. ✓


Example 4 — Case E (good suffix reoccurs, Case 1)

Figure — Boyer-Moore — bad character, good suffix heuristics

Figure kaise padhein: top row hai ANPANMAN jisme har character apne box mein hai aur neeche uska index. Indices 6–7 par do red-outlined boxes hain jo matched good suffix AN hain. Neeche drawn do red boxes, indices 3–4 par, AN ki earlier internal copy hain; kala arrow us preceding character ki taraf point karta hai. Lamba red arrow pattern ko right slide hote dikhata hai taaki earlier AN already-matched text ke neeche aa jaaye.

Step 1 — good suffix identify karo. (length ). Kyun? Mismatch ke right mein sab kuch text se match ho chuka hai; hum woh preserve karna chahte hain.

Step 2 — ke internal reoccurrences dhundho. Jaise figure mein dikhaya gaya hai, AN indices 0–1 aur 3–4 par baitha hai. Hum woh chahte hain jiske preceding character mismatched se alag ho. Kyun? Agar preceding char bhi M hota, toh agla compare identically mismatch karta — koi progress nahi.

Step 3 — indices 3–4 wali copy chunno. Uska preceding char hai ✓. AN ko indices 3–4 se indices 6–7 tak laane ke liye, shift karo. Kyun? Hum ko right slide karte hain taaki earlier valid AN already-matched text ke neeche aa jaaye.

Step 4 — shift-by-1 se sanity check. 1 se shift karne par text ki us position par aa jaata jiske baare mein hum jaante hain ki wahan A hai → guaranteed mismatch. Isliye beats 1.

Verify: Case 1 shift (end index 7) (earlier copy ka end index 4) , isliye ; matched-suffix length . ✓


Example 5 — Case F (Case 2, border = good suffix ka suffix)

Step 1 — good suffix. , length , mismatch at . Kyun? Matched-suffix length .

Step 2 — Case 1 mein kuch usable nahi, toh Case 2 par jao. Kyun? Koi earlier full copy of B nahi hai jiske preceding character ka difference ek immediate repeat mismatch avoid kare; hum ek partial overlap salvage karte hain.

Step 3 — ka longest border dhundho. ABAB ka aage se reading hai A,B,…; peeche se reading hai B,A,…. Length-2 chunk AB pehle do aur aakhri do characters dono hai → length 2 ka border (border definition yaad karo upar se). Kyun? Border ke start aur apni tail ke beech ka sabse bada overlap hai, woh eklauta alignment jo bina kisi occurrence ko skip kiye abhi bhi match kar sakta hai.

Step 4 — shift . Kyun? Slide karo taaki length-2 border prefix wahan land kare jahan length-2 border suffix tha.

Verify: ABAB ka longest border 2 hai, isliye Case-2 shift . Chhota shift sirf impossible alignments re-examine karta hai; bada wala border overlap skip kar deta hai → ek match miss ho sakta hai. ✓


Example 6 — Case D (bilkul pehle compare par mismatch)

Step 1 — matched suffix length. . Empty suffix. Kyun? Hum kuch bhi match kiye bina mismatch kar gaye, isliye good-suffix lookup hai , empty matched suffix ke liye entry.

Step 2 — cleanly compute karo. Good-suffix rule hum se sirf ek matched suffix preserve karne ko keh sakta hai; jab woh suffix empty ho toh preserve karne ke liye kuch hai hi nahi, isliye rule algorithm ke minimum legal move se zyada koi constraint nahi lagataa. Concretely : ek empty good suffix trivially har alignment par overlap karta hai, isliye ka sabse bada border-of-the-good-suffix jo ko bhi prefix karta hai uski length hai (poora pattern minus ek step), jo deta hai . Koi contradiction nahi — good-suffix rule yahan simply neutral value contribute karta hai. Kyun? Ek empty matched suffix mein yeh batane ki zero information hoti hai ki aage kahan align ho sakta hai, isliye woh se bada jump legally demand nahi kar sakta.

Step 3 — bad character. in NEEDLE → Case D ke andar Case A. . Kyun? K absent hai, isliye poora pattern use past slide kar do.

Step 4 — max lo. . Kyun? Dono rules independently safe lower bounds hain; bada wala jeetta hai. Yahan bad-character rule already maximum possible jump hit kar leta hai, aur neutral good-suffix value use beat nahi kar sakta.

Verify: ; ; final . ✓


Example 7 — Case G (full match) + context J (kaun sa rule jeetta hai)

Step 1 — full match ke baad, use karo. Har character match hone ke baad, par aa jaata hai; koi bad character lookup karne ke liye hai nahi, isliye shift poori tarah poore pattern ke liye good-suffix rule se aata hai, jo mein stored hai. Kyun? Bad-character rule trigger karne ke liye koi mismatch nahi; humein batata hai ki aagla alignment kahan ho sakta hai bina kisi overlapping occurrence ko skip kiye.

Step 2 — ABCAB ka longest border. Aage se reading A,B,C,…; peeche se reading B,A,C,…. Bade se chhote test karo: length 4 ABCA vs BCAB ✗; length 3 ABC vs CAB ✗; length 2 AB vs AB ✓. Toh sabse lamba proper border length 2 ka hai. Kyun? Agla alignment jo match kar sakta hai use ka sabse bada self-overlap reuse karna hoga — wahi exactly uska longest border hai.

Step 3 — compute karo. . Match report karne ke baad hum ko 3 se advance karte hain. Kyun? 1 ya 2 se shift karna AB… ko wahan rakhega jahan yeh re-match nahi kar sakta; 4 ya 5 se shift karna ek overlapping occurrence ko skip kar sakta hai jo abhi-abhi matched region ke andar shuru hoti hai.

Step 4 — context J twist ( of the two rules). Usi search mein kisi mismatch ke dauran hum hamesha lete hain. Do illustrative pairs:

  • agar aur ho, toh algorithm use karta hai (good suffix jeetta hai);
  • agar aur ho, toh use karta hai (bad char jeetta hai). Kyun? Har rule independently ek safe lower bound hai ek legal jump par, isliye bada bhi safe hai — hamesha dono compute karo aur max lo.

Verify: ABCAB ka border 2 hai, . Aur , . ✓


Example 8 — Case H (degenerate pattern, worst case)

Step 1 — har alignment compare karo. Har offset par, right-to-left compare karte hue, saare text A ke barabar hote hain. Hum comparisons karte hain, full match paate hain, aur (Case G) se shift karte hain. Kyun? Kuch bhi kabhi mismatch nahi karta, isliye koi bad-character skip kabhi trigger nahi hota.

Step 2 — AAA ke liye . Aage se reading A,A,…; peeche se reading A,A,…. Sabse lamba proper border: length 2 (AA pehle do aur aakhri do dono characters hai). Toh — hum sirf 1 se shift karte hain har baar. Kyun? AAA khud se har offset par overlap karta hai, isliye post-match ek hi safe move ek single step hai; bada jump overlapping AAA skip kar deta.

Step 3 — kaam count karo. Alignments ki sankhya ; har ek comparisons karta hai aur 1 se shift karta hai. Total comparisons . Kyun? Bad char useless hai (har char A hai) aur good suffix 1 se shift karta hai, isliye BM is input par naive bound par degrade ho jaata hai.

Step 4 — fix. Galil Rule already-matched region yaad rakhta hai taaki use kabhi re-compare na kare, guaranteed yahan bhi restore karta hai. Related always-linear matchers: Knuth-Morris-Pratt (KMP), Z-Algorithm (dono Borders and Prefix Function par built), aur hashing-based Rabin-Karp. Ek saath kai patterns ke liye, Aho-Corasick.

Verify: alignments ; comparisons ; AAA ka border isliye . ✓


Recall

Recall Quick self-test

Alignment offset kya hai? ::: Woh text position jiske neeche currently baitha hai; ke saath line up karta hai. Ek string ka border kya hota hai? ::: Ek substring jo prefix bhi ho aur suffix bhi, poori string se chhota (ek proper border). Kaun se case mein hota hai? ::: Case A — bad char absent, shift . Kaun sa case clamp to 1 force karta hai? ::: Case C — . Full match ke baad tum kitna shift karte ho? ::: . Good suffix ka Case 2 kab fire karta hai? ::: Sirf jab ka ek border good suffix ke suffix ke barabar ho; shift . Do rule shifts ka kyun lete hain? ::: Har ek independently ek safe lower bound hai, isliye bada bhi safe aur faster hai.