1
+ #include < iostream>
2
+ #include < vector>
3
+ #include < limits>
4
+ #include < algorithm>
5
+ #include < fstream>
6
+
7
+ #define APLHABET_SIZE CHAR_MAX
8
+
9
+ struct pattern {
10
+ std::string pat;
11
+
12
+ std::vector<size_t > badChar;
13
+ std::vector<size_t > goodSuffix;
14
+ };
15
+
16
+ void initGoodSuffix (const std::string& str, std::vector<size_t >& arg) {
17
+ arg.resize (str.size () + 1 , 0 );
18
+ std::vector<size_t > bpos (str.size () + 1 , 0 );
19
+
20
+ int currentChar = str.length ();
21
+
22
+ int beg = str.length () + 1 ;
23
+
24
+ bpos[currentChar] = beg;
25
+
26
+ while (currentChar > 0 ) {
27
+ while (beg <= str.length () && str[currentChar - 1 ] != str[beg - 1 ]) {
28
+ if (arg[beg] == 0 )
29
+ arg[beg] = beg - currentChar;
30
+
31
+ beg = bpos[beg];
32
+ }
33
+
34
+ currentChar--;
35
+ beg--;
36
+ bpos[currentChar] = beg;
37
+ }
38
+
39
+ int j = bpos[0 ];
40
+
41
+ for (size_t i = 0 ; i < str.size (); i++) {
42
+ if (arg[i] == 0 )
43
+ arg[i] = j;
44
+
45
+ if (i == j)
46
+ j = bpos[j];
47
+ }
48
+ }
49
+
50
+ void initBadChar (const std::string& str, std::vector<size_t >& arg) {
51
+ arg.resize (APLHABET_SIZE, str.length ());
52
+
53
+ for (size_t i = 0 ; i < str.length (); i++)
54
+ arg[str[i]] = str.length () - i - 1 ;
55
+ }
56
+
57
+ void initPattern (const std::string& str, pattern& arg) {
58
+ arg.pat = str;
59
+ initBadChar (str, arg.badChar );
60
+ initGoodSuffix (str, arg.goodSuffix );
61
+ }
62
+
63
+ void printTables (const pattern& arg) {
64
+ std::cout << " Bad char: " << std::endl;
65
+ for (auto x : arg.badChar )
66
+ std::cout << x << " " ;
67
+
68
+ std::cout << std::endl;
69
+ std::cout << " Good suffix: " << std::endl;
70
+
71
+ for (auto x : arg.goodSuffix )
72
+ std::cout << x << " " ;
73
+ std::cout << std::endl;
74
+ }
75
+
76
+ void search (const std::string& str, const pattern& arg) {
77
+ int indexPosition = arg.pat .size () - 1 ;
78
+
79
+ while (indexPosition < str.length ()) {
80
+ int indexString = indexPosition;
81
+ int indexPattern = arg.pat .size () - 1 ;
82
+
83
+ while (indexPattern >= 0 && str[indexString] == arg.pat [indexPattern]) {
84
+ --indexPattern;
85
+ --indexString;
86
+ }
87
+
88
+ if (indexPattern < 0 ) {
89
+ // cout in search just for the demo.
90
+ std::cout << " Matched at " << indexPosition - arg.pat .length () + 1 << std::endl;
91
+ indexPosition += arg.goodSuffix [0 ];
92
+ }
93
+ else {
94
+ indexPosition += std::max (arg.badChar [str[indexString]], arg.goodSuffix [indexPattern + 1 ]);
95
+ }
96
+ }
97
+ }
98
+
99
+ int main () {
100
+ std::string text = " This is some text where we search given pattern. Write pattern second time." ;
101
+ pattern p;
102
+ initPattern (" pattern" ,p);
103
+ search (text, p);
104
+ }
0 commit comments