From c2acc2b54c26b8e9aa7c8f9bebe9ee9f6b363afa Mon Sep 17 00:00:00 2001 From: anyncfunction <13813298288@139.com> Date: Sun, 7 Jun 2026 11:57:46 +0800 Subject: [PATCH 1/5] fix: Boyer-Moore bad character shift was dead code in for-loop The bad_character_heuristic() method used a for-loop with an assignment to the loop variable i, which was immediately overwritten by the next iteration. This caused the algorithm to degrade from O(n/m) to O(n*m) naive search. Changed to a while-loop so the shift actually takes effect. Added max(i+1, shift) guard to prevent backward skips when the mismatched character appears to the right of the mismatch in the pattern. Added edge case doctests. --- strings/boyer_moore_search.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/strings/boyer_moore_search.py b/strings/boyer_moore_search.py index ad14a504f792..8e6f79dbf75e 100644 --- a/strings/boyer_moore_search.py +++ b/strings/boyer_moore_search.py @@ -83,18 +83,30 @@ def bad_character_heuristic(self) -> list[int]: >>> bms = BoyerMooreSearch(text="ABAABA", pattern="AB") >>> bms.bad_character_heuristic() [0, 3] + + >>> bms = BoyerMooreSearch(text="AAAAA", pattern="AB") + >>> bms.bad_character_heuristic() + [] + + >>> bms = BoyerMooreSearch(text="ABABAB", pattern="ABA") + >>> bms.bad_character_heuristic() + [0, 2] + + >>> bms = BoyerMooreSearch(text="", pattern="AB") + >>> bms.bad_character_heuristic() + [] """ positions = [] - for i in range(self.textLen - self.patLen + 1): + i = 0 + while i <= self.textLen - self.patLen: mismatch_index = self.mismatch_in_text(i) if mismatch_index == -1: positions.append(i) + i += 1 else: match_index = self.match_in_pattern(self.text[mismatch_index]) - i = ( - mismatch_index - match_index - ) # shifting index lgtm [py/multiple-definition] + i = max(i + 1, mismatch_index - match_index) return positions From 27bd5b5cae9d8a9e86bff23b4172ebf5eb604ffb Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 16 Sep 2026 20:29:39 +0000 Subject: [PATCH 2/5] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- strings/boyer_moore_search.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/strings/boyer_moore_search.py b/strings/boyer_moore_search.py index b09b2ac3608f..b411de2f2c66 100644 --- a/strings/boyer_moore_search.py +++ b/strings/boyer_moore_search.py @@ -105,7 +105,7 @@ def bad_character_heuristic(self) -> list[int]: >>> bms2 = BoyerMooreSearch(text="AAAAAA", pattern="AA") >>> bms2.bad_character_heuristic() [0, 1, 2, 3, 4] - + >>> bms3 = BoyerMooreSearch(text="ABCDEF", pattern="XY") >>> bms3.bad_character_heuristic() [] From 5112b0cf77a24d19e1131fd9b37cc371809e7df7 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Wed, 16 Sep 2026 22:32:24 +0200 Subject: [PATCH 3/5] Update boyer_moore_search.py --- strings/boyer_moore_search.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/strings/boyer_moore_search.py b/strings/boyer_moore_search.py index b411de2f2c66..133d88be0a16 100644 --- a/strings/boyer_moore_search.py +++ b/strings/boyer_moore_search.py @@ -99,7 +99,7 @@ def bad_character_heuristic(self) -> list[int]: [0, 2] >>> bms = BoyerMooreSearch(text="", pattern="AB") - >>> bms.bad_character_heuristic() = None + >>> bms.bad_character_heuristic() == None True >>> bms2 = BoyerMooreSearch(text="AAAAAA", pattern="AA") From 6ece166bf2dfaad44653f19f783a345a7f901345 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Wed, 16 Sep 2026 22:35:37 +0200 Subject: [PATCH 4/5] Correct documentation for positions in BoyerMooreSearch Fixes the documentation to clarify that 'positions' contains the locations where the pattern was matched. --- strings/boyer_moore_search.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/strings/boyer_moore_search.py b/strings/boyer_moore_search.py index 133d88be0a16..e82fb323ff1d 100644 --- a/strings/boyer_moore_search.py +++ b/strings/boyer_moore_search.py @@ -29,7 +29,7 @@ class BoyerMooreSearch: bms = BoyerMooreSearch(text="ABAABA", pattern="AB") positions = bms.bad_character_heuristic() - where 'positions' contain the locations where the pattern was matched. + where 'positions' contains the locations where the pattern was matched. """ def __init__(self, text: str, pattern: str) -> None: @@ -99,8 +99,7 @@ def bad_character_heuristic(self) -> list[int]: [0, 2] >>> bms = BoyerMooreSearch(text="", pattern="AB") - >>> bms.bad_character_heuristic() == None - True + >>> bms.bad_character_heuristic() >>> bms2 = BoyerMooreSearch(text="AAAAAA", pattern="AA") >>> bms2.bad_character_heuristic() From 61761a5cbd17954b219fe7eff7e07d6b560417ff Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Wed, 16 Sep 2026 22:43:12 +0200 Subject: [PATCH 5/5] Fix grammatical issues in Boyer-Moore search comments Corrected grammatical errors in comments and docstrings. --- strings/boyer_moore_search.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/strings/boyer_moore_search.py b/strings/boyer_moore_search.py index e82fb323ff1d..7a1a8c76bb7b 100644 --- a/strings/boyer_moore_search.py +++ b/strings/boyer_moore_search.py @@ -1,5 +1,5 @@ """ -The algorithm finds the pattern in given text using following rule. +Find the pattern in the given text using the following rule. The bad-character rule considers the mismatched character in Text. The next occurrence of that character to the left in Pattern is found, @@ -11,7 +11,7 @@ a shift is proposed that moves the entirety of Pattern past the point of mismatch in the text. -If there is no mismatch then the pattern matches with text block. +If there is no mismatch, then the pattern matches the text block. Time Complexity : O(n/m) average case with bad character heuristic n=length of main string @@ -59,8 +59,8 @@ def match_in_pattern(self, char: str) -> int: def mismatch_in_text(self, current_pos: int) -> int: """ - Find the index of mis-matched character in text when compared with pattern - from last. + Find the index of the mismatched character in text when compared with pattern + from the last. Parameters : current_pos (int): current index position of text @@ -100,6 +100,7 @@ def bad_character_heuristic(self) -> list[int]: >>> bms = BoyerMooreSearch(text="", pattern="AB") >>> bms.bad_character_heuristic() + [] >>> bms2 = BoyerMooreSearch(text="AAAAAA", pattern="AA") >>> bms2.bad_character_heuristic()