TheAlgorithms/C++
1.0.0
All the algorithms implemented in C++
Toggle main menu visibility
Loading...
Searching...
No Matches
boyer_moore.cpp
Go to the documentation of this file.
1
44
45
#include <cassert>
46
#include <climits>
47
#include <cstring>
48
#include <iostream>
49
#include <string>
50
#include <vector>
51
52
#define APLHABET_SIZE CHAR_MAX
53
58
namespace
strings
{
65
namespace
boyer_moore
{
70
struct
pattern
{
71
std::string pat;
72
73
std::vector<size_t>
74
bad_char
;
76
77
std::vector<size_t>
78
good_suffix
;
80
};
81
89
void
init_good_suffix
(
const
std::string& str, std::vector<size_t>& arg) {
90
arg.resize(str.size() + 1, 0);
91
92
// border_pos[i] - the index of the longest proper suffix of str[i..] which
93
// is also a proper prefix.
94
std::vector<size_t> border_pos(str.size() + 1, 0);
95
96
size_t
current_char = str.length();
97
98
size_t
border_index = str.length() + 1;
99
100
border_pos[current_char] = border_index;
101
102
while
(current_char > 0) {
103
while
(border_index <= str.length() &&
104
str[current_char - 1] != str[border_index - 1]) {
105
if
(arg[border_index] == 0) {
106
arg[border_index] = border_index - current_char;
107
}
108
109
border_index = border_pos[border_index];
110
}
111
112
current_char--;
113
border_index--;
114
border_pos[current_char] = border_index;
115
}
116
117
size_t
largest_border_index = border_pos[0];
118
119
for
(
size_t
i = 0; i < str.size(); i++) {
120
if
(arg[i] == 0) {
121
arg[i] = largest_border_index;
122
}
123
124
// If we go pass the largest border we find the next one as we iterate
125
if
(i == largest_border_index) {
126
largest_border_index = border_pos[largest_border_index];
127
}
128
}
129
}
130
138
void
init_bad_char
(
const
std::string& str, std::vector<size_t>& arg) {
139
arg.resize(
APLHABET_SIZE
, str.length());
140
141
for
(
size_t
i = 0; i < str.length(); i++) {
142
arg[str[i]] = str.length() - i - 1;
143
}
144
}
145
153
void
init_pattern
(
const
std::string& str,
pattern
& arg) {
154
arg.pat = str;
155
init_bad_char
(str, arg.
bad_char
);
156
init_good_suffix
(str, arg.
good_suffix
);
157
}
158
165
std::vector<size_t>
search
(
const
std::string& str,
const
pattern
& arg) {
166
size_t
index_position = arg.pat.size() - 1;
167
std::vector<size_t> index_storage;
168
169
while
(index_position < str.length()) {
170
size_t
index_string = index_position;
171
int
index_pattern =
static_cast<
int
>
(arg.pat.size()) - 1;
172
173
while
(index_pattern >= 0 &&
174
str[index_string] == arg.pat[index_pattern]) {
175
--index_pattern;
176
--index_string;
177
}
178
179
if
(index_pattern < 0) {
180
index_storage.push_back(index_position - arg.pat.length() + 1);
181
index_position += arg.
good_suffix
[0];
182
}
else
{
183
index_position += std::max(arg.
bad_char
[str[index_string]],
184
arg.
good_suffix
[index_pattern + 1]);
185
}
186
}
187
188
return
index_storage;
189
}
190
200
bool
is_prefix
(
const
char
* str,
const
char
* pat,
size_t
len) {
201
if
(strlen(str) < len) {
202
return
false
;
203
}
204
205
for
(
size_t
i = 0; i < len; i++) {
206
if
(str[i] != pat[i]) {
207
return
false
;
208
}
209
}
210
211
return
true
;
212
}
213
}
// namespace boyer_moore
214
}
// namespace strings
215
220
void
and_test
(
const
char
* text) {
221
strings::boyer_moore::pattern
ands;
222
strings::boyer_moore::init_pattern
(
"and"
, ands);
223
std::vector<size_t> indexes =
strings::boyer_moore::search
(text, ands);
224
225
assert(indexes.size() == 2);
226
assert(
strings::boyer_moore::is_prefix
(text + indexes[0],
"and"
, 3));
227
assert(
strings::boyer_moore::is_prefix
(text + indexes[1],
"and"
, 3));
228
}
229
235
void
pat_test
(
const
char
* text) {
236
strings::boyer_moore::pattern
pat;
237
strings::boyer_moore::init_pattern
(
"pat"
, pat);
238
std::vector<size_t> indexes =
strings::boyer_moore::search
(text, pat);
239
240
assert(indexes.size() == 6);
241
242
for
(
const
auto
& currentIndex : indexes) {
243
assert(
strings::boyer_moore::is_prefix
(text + currentIndex,
"pat"
, 3));
244
}
245
}
246
250
static
void
tests
() {
251
const
char
* text =
252
"When pat Mr. and Mrs. pat Dursley woke up on the dull, gray \
253
Tuesday our story starts, \
254
there was nothing about pat the cloudy sky outside to pat suggest that\
255
strange and \
256
mysterious things would pat soon be happening all pat over the \
257
country."
;
258
259
and_test
(text);
260
pat_test
(text);
261
262
std::cout <<
"All tests have successfully passed!\n"
;
263
}
264
269
int
main
() {
270
tests
();
// run self-test implementations
271
return
0;
272
}
APLHABET_SIZE
#define APLHABET_SIZE
number of symbols in the alphabet we use
Definition
boyer_moore.cpp:52
pat_test
void pat_test(const char *text)
A test case in which we search for every appearance of the word 'pat'.
Definition
boyer_moore.cpp:235
and_test
void and_test(const char *text)
A test case in which we search for every appearance of the word 'and'.
Definition
boyer_moore.cpp:220
main
int main()
Main function.
Definition
generate_parentheses.cpp:110
search
for std::assert
Definition
binary_search.cpp:47
strings::boyer_moore
Functions for the Boyer Moore algorithm implementation.
Definition
boyer_moore.cpp:65
strings::boyer_moore::is_prefix
bool is_prefix(const char *str, const char *pat, size_t len)
Check if pat is prefix of str.
Definition
boyer_moore.cpp:200
strings::boyer_moore::init_pattern
void init_pattern(const std::string &str, pattern &arg)
A function that initializes pattern.
Definition
boyer_moore.cpp:153
strings::boyer_moore::search
std::vector< size_t > search(const std::string &str, const pattern &arg)
A function that implements Boyer-Moore's algorithm.
Definition
boyer_moore.cpp:165
strings::boyer_moore::init_bad_char
void init_bad_char(const std::string &str, std::vector< size_t > &arg)
A function that preprocess the bad char table.
Definition
boyer_moore.cpp:138
strings::boyer_moore::init_good_suffix
void init_good_suffix(const std::string &str, std::vector< size_t > &arg)
A function that preprocess the good suffix thable.
Definition
boyer_moore.cpp:89
strings
String algorithms.
Definition
boyer_moore.cpp:58
tests
Testcases to check Union of Two Arrays.
strings::boyer_moore::pattern
A structure representing all the data we need to search the preprocessed pattern in text.
Definition
boyer_moore.cpp:70
strings::boyer_moore::pattern::good_suffix
std::vector< size_t > good_suffix
Definition
boyer_moore.cpp:78
strings::boyer_moore::pattern::bad_char
std::vector< size_t > bad_char
Definition
boyer_moore.cpp:74
strings
boyer_moore.cpp
Generated by
1.18.0