-
Notifications
You must be signed in to change notification settings - Fork 0
/
rabin_karp_substring_search_v2.cpp
86 lines (70 loc) · 2.17 KB
/
rabin_karp_substring_search_v2.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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <string>
#include <iostream>
namespace rabin_karp
{
const int BASE = (1 << 8);
const int MOD = 104729;
int soloHash(const std::string& s, int startIdx, int endIdx)
{
int base = 1;
int out = 0;
for (int i = startIdx; i <= endIdx; i++)
{
out *= BASE;
out = out + s[i] * base;
out = out % MOD;
}
return out;
}
int rollHash(const std::string& s, int startIdx, int endIdx, int prevHash)
{
int leftBaseOffset = s[startIdx - 1];
for (int i = startIdx; i < endIdx; i++)
{
leftBaseOffset *= BASE;
leftBaseOffset %= MOD;
}
int out = ((prevHash + MOD - leftBaseOffset) * BASE + s[endIdx]) % MOD;
return out;
}
// сравнине строк
bool stringsMatch(const std::string& needle, const std::string& haystack, std::size_t haystackOffset)
{
for (std::size_t i = 0; i < needle.size(); i++)
{
if(needle[i] != haystack[i + haystackOffset])
return false;
}
return true;
}
// поиск подстроки
int search_substring(const std::string& haystack, const std::string& needle)
{
const auto haystackLen = haystack.size();
const auto needleLen = needle.size();
if(needleLen == 0)
return 0;
if(needleLen > haystackLen)
return -1;
const auto needleHash = soloHash(needle, 0, needleLen - 1);
auto substrHash = soloHash(haystack, 0, needleLen - 1);
if(needleHash == substrHash)
{
if(stringsMatch(needle, haystack, 0))
return 0;
}
for(int i = 1; i <= haystackLen - needleLen; i++)
{
substrHash = rollHash(haystack, i, i + needleLen - 1, substrHash);
if(needleHash != substrHash)
continue;
if(stringsMatch(needle, haystack, i))
return i;
}
return -1;
}
}
int main()
{
std::cout << "found " << rabin_karp::search_substring("Hello World", "lo World");
}