Skip to content

Commit e382dce

Browse files
committed
rabin-karp algotithm
1 parent f537e33 commit e382dce

2 files changed

Lines changed: 121 additions & 1 deletion

File tree

3/chained_hashing.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ class HashTable
8989
long long tmp;
9090

9191
while (i < len) {
92-
tmp = i ? str[i] * pow(x, i) : str[i];
92+
tmp = str[i] * pow(x, i);
9393
res += tmp;
9494
++i;
9595
}

3/rabin_karp.cpp

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
#include <iostream>
2+
#include <vector>
3+
4+
#define q 1000000007l
5+
#define x 31
6+
7+
class RabinKarp
8+
{
9+
public:
10+
RabinKarp(std::string const & pattern, std::string const & text): _pattern(pattern) {
11+
//std::cout << __FUNCTION__ << std::endl;
12+
_length = pattern.length();
13+
_patternHash = hash(pattern.c_str());
14+
check(text);
15+
_occ.shrink_to_fit();
16+
}
17+
18+
~RabinKarp() {}
19+
20+
void showOccurences() {
21+
//std::cout << __FUNCTION__ << std::endl;
22+
for (unsigned i : _occ)
23+
std::cout << i << " ";
24+
std::cout << std::endl;
25+
}
26+
27+
std::vector<unsigned> const & getOccurences() {
28+
return _occ;
29+
}
30+
private:
31+
std::vector<unsigned> _occ;
32+
size_t _length;
33+
unsigned _patternHash;
34+
std::string _pattern;
35+
36+
void check(std::string const & str) {
37+
//std::cout << __FUNCTION__ << std::endl;
38+
size_t i = 1;
39+
long long newHash;
40+
long long oldHash;
41+
long long tmp;
42+
char newChar;
43+
char oldChar;
44+
size_t len = str.length() - _length + 1;
45+
46+
oldChar = str[0];
47+
oldHash = hash(str.c_str());
48+
if (oldHash == _patternHash && equal(str, 0))
49+
_occ.push_back(0);
50+
while (i < len) {
51+
newChar = str[i + _length -1];
52+
tmp = oldHash - oldChar;
53+
tmp = ((tmp % q) + q) %q;
54+
tmp /= x;
55+
56+
newHash = tmp + ( ((newChar * pow(x, _length - 1))%q) + q) % q;
57+
newHash %= q;
58+
std::cout << "i = " << i <<"; oldChar = " << oldChar << "; oldHash = " << oldHash
59+
<< "; newChar = " << newChar << "; newHash " << newHash << "; _patternHash: "
60+
<< _patternHash << std::endl;
61+
if ( newHash == _patternHash && equal(str, i))
62+
_occ.push_back(i);
63+
oldHash = newHash;
64+
oldChar = str[i];
65+
++i;
66+
}
67+
}
68+
69+
bool equal(std::string const & str, size_t index) {
70+
//std::cout << __FUNCTION__ << std::endl;
71+
size_t i = 0;
72+
while (i < _length) {
73+
if (_pattern[i] != str[index])
74+
return false;
75+
++index;
76+
++i;
77+
}
78+
return true;
79+
}
80+
81+
long long pow(long long base, size_t power) {
82+
//std::cout << __FUNCTION__ << std::endl;
83+
long long res = 1;
84+
if (power == 0 || base == 1)
85+
return 1;
86+
for (size_t i = 0; i < power; ++i) {
87+
res *= base;
88+
res %= q;
89+
}
90+
return res;
91+
}
92+
93+
long long hash(char const* str) {
94+
//std::cout << __FUNCTION__ << std::endl;
95+
size_t i = 0;
96+
long long res = 0;
97+
long long tmp;
98+
99+
while (i < _length) {
100+
tmp = str[i] * pow(x, i);
101+
res += tmp %q;
102+
tmp = ((tmp%q) + q) %q;
103+
++i;
104+
}
105+
res = ((res%q) + q)% q;
106+
return res;
107+
}
108+
};
109+
110+
int main(void)
111+
{
112+
std::string pattern;
113+
std::string text;
114+
115+
std::cin >> pattern >> text;
116+
117+
RabinKarp(pattern, text).showOccurences();
118+
119+
return 0;
120+
}

0 commit comments

Comments
 (0)