Skip to content
This repository was archived by the owner on Nov 29, 2020. It is now read-only.

Commit f9c9234

Browse files
committed
RabinKarpMatcher.cpp
1 parent 437dbd8 commit f9c9234

File tree

4 files changed

+82
-4
lines changed

4 files changed

+82
-4
lines changed

ModularExponentiation.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ template <typename T>
3232
T ModularExponentiation(T a, T b, T n) {
3333
T c = 0;
3434
T d = 1;
35-
for (T i = log2(b); i >= 0; i--) {
35+
assert(b >= 0);
36+
if (b == 0)
37+
return 1;
38+
for (T i = log2(b) + 1; i-- > 0;) {
3639
c *= 2;
3740
d = d * d % n;
3841
if (b & 1 << i) {

NaiveStringMatcher.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,10 @@ void NaiveStringMatcher(const std::vector<T>& S, const std::vector<T>& P,
5858
int main(int argc, char *argv[]) {
5959
const size_t n = get_argv(argc, argv, 1, 40);
6060
const size_t m = get_argv(argc, argv, 2, 3);
61-
const size_t s = get_argv(argc, argv, 3, 2);
61+
const size_t d = get_argv(argc, argv, 3, 2);
6262
std::vector<char> S, P;
63-
random_integers<char>(S, 'a', 'a' + s, n);
64-
random_integers<char>(P, 'a', 'a' + s, m);
63+
random_integers<char>(S, 'a', 'a' + d, n);
64+
random_integers<char>(P, 'a', 'a' + d, m);
6565
output_integers(S, "");
6666
output_integers(P, "");
6767
std::vector<size_t> ans;

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@
206206
| 31 | MillerRabin.cpp | Miller Rabin | 970 |
207207
| 31 | PollardRho.cpp | Pollard Rho | 977 |
208208
| 32 | NaiveStringMatcher.cpp | Naive String Matcher | 988 |
209+
| 32 | RabinKarpMatcher.cpp | Rabin Karp Matcher | 993 |
209210

210211
# Supplementary Files
211212
* `utils.h`: Utils

RabinKarpMatcher.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//
2+
// algorithm - some algorithms in "Introduction to Algorithms", third edition
3+
// Copyright (C) 2018 lxylxy123456
4+
//
5+
// This program is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU Affero General Public License as
7+
// published by the Free Software Foundation, either version 3 of the
8+
// License, or (at your option) any later version.
9+
//
10+
// This program is distributed in the hope that it will be useful,
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
// GNU Affero General Public License for more details.
14+
//
15+
// You should have received a copy of the GNU Affero General Public License
16+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
//
18+
19+
#ifndef MAIN
20+
#define MAIN
21+
#define MAIN_RabinKarpMatcher
22+
#endif
23+
24+
#ifndef FUNC_RabinKarpMatcher
25+
#define FUNC_RabinKarpMatcher
26+
27+
#include "utils.h"
28+
29+
#include "ModularExponentiation.cpp"
30+
#include "NaiveStringMatcher.cpp"
31+
32+
template <typename T>
33+
void RabinKarpMatcher(const std::vector<T>& S, const std::vector<T>& P,
34+
size_t d, size_t q, T o, std::vector<size_t>& ans) {
35+
size_t n = S.size(), m = P.size();
36+
size_t h = ModularExponentiation(d, m - 1, q);
37+
size_t p = 0, t = 0;
38+
for (size_t i = 0; i < m; i++) {
39+
p = (d * p + P[i] - o) % q;
40+
t = (d * t + S[i] - o) % q;
41+
}
42+
for (size_t s = 0; s <= n - m; s++) {
43+
if (p == t && equal(P, 0, S, s, m))
44+
ans.push_back(s);
45+
if (s < n - m)
46+
t = (d * (t - (S[s] - o) * h) + S[s + m] - o) % q;
47+
}
48+
}
49+
#endif
50+
51+
#ifdef MAIN_RabinKarpMatcher
52+
int main(int argc, char *argv[]) {
53+
const size_t n = get_argv(argc, argv, 1, 40);
54+
const size_t m = get_argv(argc, argv, 2, 3);
55+
const size_t d = get_argv(argc, argv, 3, 2);
56+
const size_t compute = get_argv(argc, argv, 4, 1);
57+
std::vector<char> S, P;
58+
random_integers<char>(S, 'a', 'a' + d, n);
59+
random_integers<char>(P, 'a', 'a' + d, m);
60+
output_integers(S, "");
61+
output_integers(P, "");
62+
std::vector<size_t> ans;
63+
RabinKarpMatcher(S, P, d, 1000000007, 'a', ans);
64+
output_integers(ans);
65+
if (compute) {
66+
std::vector<size_t> ans1;
67+
NaiveStringMatcher(S, P, ans1);
68+
output_integers(ans1);
69+
std::cout << std::boolalpha << (ans == ans1) << std::endl;
70+
}
71+
return 0;
72+
}
73+
#endif
74+

0 commit comments

Comments
 (0)