-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathd_boyer_moore.cpp
66 lines (59 loc) · 1.61 KB
/
d_boyer_moore.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <iostream>
#include <list>
std::list<int> substring_find(std::string const& main, std::string const& substring) {
const int size = substring.size();
int bad_chars[70];
std::fill(bad_chars, bad_chars + 70, size);
for (int i = 0; i < size - 1; ++i) {
bad_chars[substring[i] - 'A'] = size - 1 - i;
}
int good_shifts[size];
int f[size];
std::fill(good_shifts, good_shifts + size, 0);
std::fill(f, f + size, 0);
int j = size;
f[size - 1] = j;
for (int i = size - 1; i >= 0; --i) {
// if (size > 1e6) break;
while (j <= size - 1 && substring[i] != substring[j]) {
if (good_shifts[j] == 0) {
good_shifts[j] = j - i;
}
j = f[j];
}
f[i - 1] = --j;
}
int p = f[0];
for (j = 0; j < size - 1; ++j) {
if (good_shifts[j] == 0) {
good_shifts[j] = p;
}
if (j == p) {
p = f[p];
}
}
std::list<int> coordinates;
for (int i = size - 1; i < main.size(); ) {
int j = size - 1;
while (substring[j] == main[i]) {
if (j == 0) {
coordinates.push_back(i);
break;
}
--i;
--j;
}
i += std::max(size - 1 - j + good_shifts[j], bad_chars[main[i] - 'A']);
}
return std::move(coordinates);
}
int main() {
std::string main, str;
std::cin >> str >> main;
auto result = substring_find(main, str);
std::cout << result.size() << '\n';
for (auto i: result) {
std::cout << i + 1 << ' ';
}
return 0;
}