TheAlgorithms-Python
87 строк · 2.7 Кб
1"""
2The algorithm finds the pattern in given text using following rule.
3
4The bad-character rule considers the mismatched character in Text.
5The next occurrence of that character to the left in Pattern is found,
6
7If the mismatched character occurs to the left in Pattern,
8a shift is proposed that aligns text block and pattern.
9
10If the mismatched character does not occur to the left in Pattern,
11a shift is proposed that moves the entirety of Pattern past
12the point of mismatch in the text.
13
14If there no mismatch then the pattern matches with text block.
15
16Time Complexity : O(n/m)
17n=length of main string
18m=length of pattern string
19"""
20
21from __future__ import annotations22
23
24class BoyerMooreSearch:25def __init__(self, text: str, pattern: str):26self.text, self.pattern = text, pattern27self.textLen, self.patLen = len(text), len(pattern)28
29def match_in_pattern(self, char: str) -> int:30"""finds the index of char in pattern in reverse order31
32Parameters :
33char (chr): character to be searched
34
35Returns :
36i (int): index of char from last in pattern
37-1 (int): if char is not found in pattern
38"""
39
40for i in range(self.patLen - 1, -1, -1):41if char == self.pattern[i]:42return i43return -144
45def mismatch_in_text(self, current_pos: int) -> int:46"""47find the index of mis-matched character in text when compared with pattern
48from last
49
50Parameters :
51current_pos (int): current index position of text
52
53Returns :
54i (int): index of mismatched char from last in text
55-1 (int): if there is no mismatch between pattern and text block
56"""
57
58for i in range(self.patLen - 1, -1, -1):59if self.pattern[i] != self.text[current_pos + i]:60return current_pos + i61return -162
63def bad_character_heuristic(self) -> list[int]:64# searches pattern in text and returns index positions65positions = []66for i in range(self.textLen - self.patLen + 1):67mismatch_index = self.mismatch_in_text(i)68if mismatch_index == -1:69positions.append(i)70else:71match_index = self.match_in_pattern(self.text[mismatch_index])72i = (73mismatch_index - match_index74) # shifting index lgtm [py/multiple-definition]75return positions76
77
78text = "ABAABA"79pattern = "AB"80bms = BoyerMooreSearch(text, pattern)81positions = bms.bad_character_heuristic()82
83if len(positions) == 0:84print("No match found")85else:86print("Pattern found in following positions: ")87print(positions)88