Skip to content

Commit 208d12e

Browse files
authored
Merge pull request #229 from Zac-HD/example-dashboard
Add a new example dashboard
2 parents 285f9d4 + 185414c commit 208d12e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+7472
-32
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
from typing import Dict, List
2+
3+
4+
def boyer_moore_search(text: str, pattern: str) -> List[int]:
5+
"""
6+
Full Boyer-Moore string search algorithm implementation.
7+
8+
Implements both the bad character rule and good suffix rule for optimal performance.
9+
10+
Args:
11+
text: The text to search in
12+
pattern: The pattern to search for
13+
14+
Returns:
15+
List of starting positions where pattern matches in text
16+
"""
17+
if not pattern:
18+
return list(range(len(text) + 1))
19+
20+
n, m = len(text), len(pattern)
21+
if m > n:
22+
return []
23+
24+
bad_char_table = _build_bad_char_table(pattern)
25+
good_suffix_table = _build_good_suffix_table(pattern)
26+
27+
matches = []
28+
i = m - 1 # Position in text
29+
30+
while i < n:
31+
j = m - 1 # Position in pattern
32+
k = i # Current position in text
33+
34+
while j >= 0 and text[k] == pattern[j]:
35+
j -= 1
36+
k -= 1
37+
38+
if j == -1:
39+
matches.append(k + 1)
40+
i += good_suffix_table[0]
41+
else:
42+
bad_char_shift = _get_bad_char_shift(bad_char_table, text[k], j, m)
43+
good_suffix_shift = good_suffix_table[j + 1]
44+
45+
shift = max(bad_char_shift, good_suffix_shift)
46+
i += shift
47+
48+
return matches
49+
50+
51+
def _build_bad_char_table(pattern: str) -> Dict[str, int]:
52+
"""
53+
Build the bad character rule table.
54+
55+
For each character in the pattern, store the rightmost occurrence position
56+
from the right end of the pattern.
57+
"""
58+
m = len(pattern)
59+
table = {}
60+
61+
for i in range(m - 1):
62+
table[pattern[i]] = m - 1 - i
63+
64+
return table
65+
66+
67+
def _get_bad_char_shift(table: Dict[str, int], char: str, j: int, m: int) -> int:
68+
"""
69+
Calculate shift using bad character rule.
70+
71+
Args:
72+
table: Bad character table
73+
char: Mismatched character from text
74+
j: Current position in pattern
75+
m: Length of pattern
76+
77+
Returns:
78+
Shift amount
79+
"""
80+
if char in table:
81+
return max(1, table[char] - (m - 1 - j))
82+
else:
83+
return max(1, m - j)
84+
85+
86+
def _build_border_table(pattern: str) -> List[int]:
87+
"""
88+
Build the border table for the good suffix rule.
89+
90+
A border is a proper suffix that is also a proper prefix.
91+
"""
92+
m = len(pattern)
93+
border = [0] * (m + 1)
94+
95+
i = 1
96+
j = 0
97+
98+
while i < m:
99+
if pattern[i] == pattern[j]:
100+
border[i + 1] = j + 1
101+
i += 1
102+
j += 1
103+
elif j > 0:
104+
j = border[j]
105+
else:
106+
border[i + 1] = 0
107+
i += 1
108+
109+
return border
110+
111+
112+
def _build_good_suffix_table(pattern: str) -> List[int]:
113+
"""
114+
Build the good suffix rule table.
115+
116+
This table contains shift values for when a good suffix is found.
117+
"""
118+
m = len(pattern)
119+
good_suffix = [m] * (m + 1)
120+
border = _build_border_table(pattern)
121+
122+
# Case 1: Exact match
123+
good_suffix[0] = 1
124+
125+
# Case 2: Good suffix exists
126+
for i in range(m):
127+
j = m - border[i + 1]
128+
if j < m:
129+
good_suffix[j] = m - 1 - i
130+
131+
# Case 3: No good suffix, shift by pattern length
132+
for i in range(1, m):
133+
if good_suffix[i] == m:
134+
good_suffix[i] = m - border[i]
135+
136+
return good_suffix

0 commit comments

Comments
 (0)