Pagini recente » Borderou de evaluare (job #3299631) | Borderou de evaluare (job #3341211) | Borderou de evaluare (job #3342642) | Istoria paginii utilizator/testuser64 | Cod sursa (job #3333393)
#include <fstream>
#include <ios>
#include <vector>
#include <cstdint>
using namespace std;
using Vector = vector<pair<uint32_t, uint32_t>>;
static inline constexpr uint64_t MOD = 1e9 + 7;
static inline constexpr uint64_t BASE = 131;
ifstream fin("strmatch.in");
ofstream fout("strmatch.out");
uint64_t basePow = 1;
void computeBasePow(const uint32_t& e)
{
for(uint32_t i=1; i <= e; i++)
{
basePow *= BASE;
basePow %= MOD;
}
}
uint64_t computeHash(const string& s)
{
uint64_t h = 0;
for(const auto& f: s)
{
h = h*BASE + f;
h %= MOD;
}
return h;
}
uint64_t nextHash(const uint64_t& prevHash, const char& prevCh, const char& nextCh)
{
return ((prevHash - prevCh*basePow%MOD) * BASE % MOD + nextCh) % MOD;
}
Vector RabinKarp(const string& a, const string& b)
{
computeBasePow(a.size()-1);
Vector v;
uint64_t hashA = computeHash(a);
uint64_t hashB = computeHash(b.substr(0, a.size()));
for(uint32_t i = a.size()-1; i < b.size(); i++)
{
if(hashA == hashB)
{
if(a == b.substr(i + 1 - a.size(), a.size()))
{
v.push_back(make_pair(i + 1 - a.size(), i));
}
}
hashB = nextHash(hashB, b[i+1], b[i + 1 - a.size()]);
}
return v;
}
int main()
{
ios_base::sync_with_stdio(false);
fin.tie(nullptr);
fout.tie(nullptr);
string a, b;
fin >> a >> b;
b = b + '0';
Vector v = RabinKarp(a, b);
fout << v.size();
for(const auto& f: v)
{
fout << '\n';
fout << f.first << ' ' << f.second;
}
}