Я написал код для поиска подстроки в другой строке с использованием хэширования, но это дает мне неверный результат.
Описание работы кода:
- Сохранение первой
n
степеней p=31
в массиве pows
. - Сохранение хэшей для каждой подстроки
s[0..i]
в массиве h
. - Вычисление га sh для каждой подстроки длиной 9 с использованием массива
h
и сохраните его в наборе. - Ха sh строка
t
и сохраните ее ха sh. - Сравните ха sh из
t
и хэшей в наборе.
Ха sh h[n2-1]
должно существовать в наборе, но его нет. Не могли бы вы помочь мне найти ошибку в коде?
Примечание: Когда я использую модульную инверсию вместо умножения на pows[i-8]
, код работает хорошо.
#include <bits/stdc++.h>
#define m 1000000007
#define N (int)2e6 + 3
using namespace std;
long long pows[N], h[N], h2[N];
set<int> ss;
int main() {
string s = "www.cplusplus.com/forum";
// powers array
pows[0] = 1;
int n = s.length(), p = 31;
for (int i = 1; i < n; i++) {
pows[i] = pows[i - 1] * p;
pows[i] %= m;
}
// hash from 0 to i array
h[0] = s[0] - 'a' + 1;
for (int i = 1; i < n; i++) {
h[i] = h[i - 1] + (s[i] - 'a' + 1) * pows[i];
h[i] %= m;
}
// storing each hash with 9 characters in a set
ss.insert(h[8]);
for (int i = 9; i < n; i++) {
int tp = h[i] - h[i - 9] * pows[i - 8];
tp %= m;
tp += m;
tp %= m;
ss.insert(tp);
}
// print hashes with 9 characters
set<int>::iterator itr = ss.begin();
while (itr != ss.end()) {
cout << *(itr++) << " ";
}
cout << endl;
// t is the string that i want to check if it is exist in s
string t = "cplusplus";
int n2 = t.length();
h2[0] = t[0] - 'a' + 1;
for (int i = 1; i < n2; i++) {
h2[i] = h2[i - 1] + (t[i] - 'a' + 1) * pows[i];
h2[i] %= m;
}
// print t hash
cout << h2[n2 - 1] << endl;
return 0;
}