Skip to content

Commit f4592d8

Browse files
committed
Add boyer moore search
1 parent 4478fca commit f4592d8

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed

boyer_moore_horspool.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#include <string_view> // std::string_view
2+
#include <optional> // std::optional
3+
#include <array> // std::array
4+
#include <iostream> // std::cout
5+
6+
7+
struct SearchPattern {
8+
std::string_view needle;
9+
std::array<char, 256> bad_char_table;
10+
SearchPattern(const std::string_view needle) : needle(needle) {
11+
// compute bad char table
12+
bad_char_table = {};
13+
14+
// Rule 1
15+
// Characters not in the needle jump the length of the needle.
16+
bad_char_table.fill(needle.length());
17+
18+
19+
// Rule 2
20+
// Characters in the needle except last character jump:
21+
// length of needle - last position of character - 1
22+
for (std::size_t i = 0; i < needle.length(); i++) {
23+
bad_char_table[needle[i]] = needle.length() - i - 1;
24+
}
25+
}
26+
};
27+
28+
/** Returns index of first occurrance of pattern in haystack. */
29+
std::optional<std::size_t> boyer_moore_horspool(SearchPattern pattern, std::string_view haystack) {
30+
for (std::size_t h = 0; h < haystack.length() - pattern.needle.length() + 1;) {
31+
// Search this placement of the needle.
32+
bool found = false;
33+
for (std::size_t n = pattern.needle.length() - 1; ; n--) {
34+
// Check the needle in reverse.
35+
if (haystack[h + n] != pattern.needle[n]) {
36+
// Bad character found.
37+
found = false;
38+
// Jump based on the bad character table.
39+
h += pattern.bad_char_table[haystack[h + n]];
40+
break;
41+
}
42+
if (n == 0) {
43+
break;
44+
}
45+
}
46+
if (found) {
47+
return h;
48+
}
49+
}
50+
51+
// Not found in the haystack.
52+
return std::nullopt;
53+
}
54+
55+
int main() {
56+
auto needle = SearchPattern{ "abc" };
57+
auto haystack = "aa abc ddef";
58+
auto index = boyer_moore_horspool(needle, haystack);
59+
if (index) {
60+
std::cout << "found at index " << index.value() << '\n' << std::flush;
61+
} else {
62+
std::cout << "not found" << std::endl;
63+
}
64+
}

0 commit comments

Comments
 (0)