Pagini recente » Cod sursa (job #880281) | Cod sursa (job #2788607) | Cod sursa (job #2279716) | Cod sursa (job #1437865) | Cod sursa (job #2217413)
#include <fstream>
using namespace std;
ifstream in("strmatch.in");
ofstream out("strmatch.out");
const int DIM = 2000001, MOD1 = 100007, MOD2 = 100021, B = 73;
char text[DIM], pattern[DIM];
int T, P, nrap, ap[1001];
int hashP1, hashP2, hashT1, hashT2; //double hashing: daca ambele hashuri sunt egale atunci este ~100% sigur ca avem match
inline int h(int x, int c, const int MOD)
{
return (x * B + c) % MOD;
}
void Rabin_Karp(char *pattern, int P, char *text, int T)
{
int B1 = 1, B2 = 1; //reprezinta B ^ (P - 1) mod MOD1, respectiv mod MOD2
for(int i = 0; i < P; i++)
{
hashP1 = h(hashP1, pattern[i], MOD1);
hashP2 = h(hashP2, pattern[i], MOD2);
if(i)
{
B1 = h(B1, 0, MOD1);
B2 = h(B2, 0, MOD2);
}
}
for(int i = 0; i < P; i++)
{
hashT1 = h(hashT1, text[i], MOD1);
hashT2 = h(hashT2, text[i], MOD2);
}
if(hashT1 == hashP1 && hashT2 == hashP2)
ap[++nrap] = 0;
for(int i = P; i < T; i++)
{
//eliminam din hashuri caracterele de dinainte, a.i. sa ramanem cu o secventa de lg P
hashT1 = h((hashT1 - text[i - P] * B1) % MOD1 + MOD1, text[i], MOD1);
hashT2 = h((hashT2 - text[i - P] * B2) % MOD2 + MOD2, text[i], MOD2);
if(hashT1 == hashP1 && hashT2 == hashP2)
ap[++nrap] = i - P + 1;
}
}
int main()
{
in.getline(pattern, DIM);
P = in.gcount() - 1;
in.getline(text, DIM);
T = in.gcount() - 1;
if(P > T)
{
out << 0;
return 0;
}
Rabin_Karp(pattern, P, text, T);
out << nrap << '\n';
nrap = min(nrap, 1000);
for(int i = 1; i <= nrap; i++)
out << ap[i] << ' ';
return 0;
}