Cod sursa(job #345977)
/*
Algoritmul Rabin-Karp in complexitate O(n+m).
*/
#include <iostream>
//#include <conio.h>
#include <cstring>
using namespace std;
// dimensiunea maxima a textului
#define N 2000002
// dimensiunea maxima a modelului
#define M 2000002
// baza in care se lucreaza este 255
#define D 255
// un numar prim foarte mare
#define modHash1 100007
// un numar prim foarte mare
#define modHash2 100021
// textul
char *T;
// modelul
char *P;
// dimensiunea textului
int n;
// dimensiunea modelului
int m;
int sol[1024];
int nrsol;
int main() {
int h1P=0, h2P=0, h1=0, h2=0;
T=new char[N];
P=new char[M];
for(int i = 0 ; i < N; ++i) T[i] = 0;
for(int i = 0; i < M; ++i) P[i] = 0;
freopen("strmatch.in","r",stdin);
gets(P);
gets(T);
n=strlen(T);
m=strlen(P);
int pow1D=D%modHash1;
int pow2D=D%modHash2;
for (int i=2; i<=m-1; i++)
pow1D=(pow1D*D)%modHash1, pow2D=(pow2D*D)%modHash2;
// calculam hash-ul modelului
for (int i=0; i<m; i++)
h1P=(h1P*D+P[i])%modHash1, h2P=(h2P*D+P[i])%modHash2;
// calculam 2 hash-uri pentru prima secventa m-1 a textului
for (int i=0; i<m-1; i++)
h1=((h1*D)%modHash1+T[i]%modHash1)%modHash1, h2=((h2*D)%modHash2+T[i]%modHash2)%modHash2;
for (int i=m-1; i<n; i++) {
// adaug cifra
h1=((h1*D)%modHash1+T[i]%modHash1)%modHash1;
h2=((h2*D)%modHash2+T[i]%modHash2)%modHash2;
if (h1==h1P && h2==h2P)
{
if(nrsol < 1000)
sol[++nrsol] = i-m;
else ++nrsol;
}
// scad cifra
h1-= (T[i-m+1]*pow1D%modHash1)%modHash1;
h2-= (T[i-m+1]*pow2D%modHash2)%modHash2;
while (h1<0) h1+=modHash1;
while (h2<0) h2+=modHash2;
}
// getch();
freopen("strmatch.out","w",stdout);
printf("%d\n", nrsol);
for(int i = 1; i <= min(nrsol, 1000); ++i)
printf("%d ", sol[i]);
return 0;
}