Answer the question
In order to leave comments, you need to log in
Rabin-Karp algorithm. Where is the mistake?
Wrote a polynomial hash function without taking the remainder, can there be a mistake in this? The algorithm fails the second test.
#include <fstream>
#include <vector>
#include <string>
int x = 53;
int hash(const std::string& t, std::vector<int>& degree_x)
{
int h = 0;
for (int m = degree_x.size() - 2, i = 0; i < t.size(); m--, i++)
{
h += (t[i] - 'A' + 1) * degree_x[m];
}
return h;
}
bool equal(const std::string& t, const std::string& p)
{
for (int i = 0; i < t.size(); i++)
{
if (t[i] != p[i])
return false;
}
return true;
}
void buildH(std::string& t, std::string& p, std::vector<int>& H, std::vector<int>& degree_x)
{
int n = t.size();
int m = p.size();
H[0] = hash(t.substr(0, m), degree_x);
for (int i = 1; i < n - m + 1; i++)
{
H[i] = (H[i - 1] * x - (t[i - 1] - 'A' + 1) * degree_x.back() + (t[i + m - 1] - 'A' + 1));
}
}
void Rabin_Karp(std::string& t, std::string& p, std::vector<int>& H, std::vector<int>& degree_x, std::vector<int>& answer)
{
if (p.size() > t.size())
return;
buildH(t, p, H, degree_x);
int hash_p = hash(p, degree_x);
int n = t.size();
int m = p.size();
for (int i = 0; i < n - m + 1; i++)
{
if (H[i] != hash_p)
continue;
else if(equal(t.substr(i, m), p))
{
answer.push_back(i + 1);
}
}
}
int main()
{
std::ifstream fin;
std::ofstream fout;
fin.open("search2.in");
fout.open("search2.out");
std::string p, t;
fin >> p >> t;
std::vector<int> degree_x;
std::vector<int> answer;
int val = 1;
for (int i = 0; i < p.size() + 1; i++)
{
degree_x.push_back(val);
val *= x;
}
std::vector<int> H(t.size() - p.size() + 1, 0);
Rabin_Karp(t, p, H, degree_x, answer);
fout << answer.size() << '\n';
for (auto el : answer)
{
fout << el << " ";
}
fin.close();
fout.close();
return 0;
}
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question