11const int modulus = 1e9 + 7;
20size_t compute_hash(
const std::string& str,
size_t start,
size_t end) {
22 size_t hash_value = 0;
23 for (
size_t i = start; i < end; i++) {
24 hash_value = (hash_value + (size_t(str[end - i - 1]) * curr_mod) % modulus) % modulus;
25 curr_mod = (curr_mod * base) % modulus;
46bool check_collision(
const std::string& str1,
size_t start1,
const std::string& str2,
size_t start2,
48 for (
size_t i = 0; i < length; ++i) {
49 if (str1[start1 + i] != str2[start2 + i]) {
70std::vector<size_t> rabin_karp(
const std::string& text,
const std::string& pattern) {
71 std::vector<size_t> result;
72 size_t pattern_length = pattern.length();
73 size_t text_length = text.length();
75 if (pattern_length == 0) {
77 for (
size_t i = 0; i <= text_length; i++) {
83 if (text_length < pattern_length) {
90 size_t pattern_hash = compute_hash(pattern, 0, pattern_length);
91 size_t text_hash = compute_hash(text, 0, pattern_length);
95 for (
int i = 0; i < pattern_length - 1; ++i)
96 power = (power * base) % modulus;
98 for (
size_t i = 0; i <= text_length - pattern_length; ++i) {
99 if (pattern_hash == text_hash && check_collision(text, i, pattern, 0, pattern_length)) {
103 if (i < text_length - pattern_length) {
105 (base * (text_hash - ((size_t)text[i] * power % modulus) + modulus) % modulus +
106 (size_t)text[i + pattern_length]) %