Pagini recente » Cod sursa (job #920558) | Cod sursa (job #2527507) | Cod sursa (job #2409387) | Cod sursa (job #455991) | Cod sursa (job #1968810)
#include <stdint.h>
#include <fstream>
#include <string.h>
#define nmax 2000001
using namespace std;
fstream f1("strmatch.in", ios::in);
fstream f2("strmatch.out", ios::out);
char pa[nmax], sir[nmax];
int32_t n, m, poz[1001], nrpoz;
int16_t d=126, p, maxi, secv;///d= nrmaxim caractere distincte text
const int16_t q=131;
///maxi= (d^(m-1))%q
///q=nr prim pt care fct hash ia val intre 0 si q-1
///idee: pt a nu verifica fiecare secv de lungime m daca se potriveste cu patternul
///atribuim printr o fct hash patternului si fiecarei secv de lungime m un numar
///intreg, cuprins intre 0 si q-1 si facem verificarea de potrivire
///doar daca h(pa)(not p)= h(sir_i)(sir_i=secv dem caractere, care incepe de pe pozitia i)
void pattern_primasecv()
{
///p= pa[0]*d^m+ pa[1]*d^(m-1)+...+pa[m-1]*d^(m-1)
///secv= sir[0]*d^m+ sir[1]*d^(m-1)+...+sir[m-1]*d^(m-1)
int32_t i;
for(i=0; i<m; i++)
{
p=(p*d+pa[i])%q;
secv=(secv*d+ sir[i])%q;
}
}
int64_t maxim()
{
int32_t i;
int64_t var=1;
for(i=1; i<m; i++)
{
var*=d;
var%=q;
}
return var;
}
int32_t potrivire(int32_t in)
{
int32_t i, j;
for(i=in, j=0; j<m; i++, j++)
if(sir[i]!=pa[j]) return 0;
return 1;
}
void rabin_karp()
{
int32_t i;
for(i=0; (i<=n-m)&&(nrpoz<1000); i++)///afisezi doar primele 1000 de potriviri(indicii)
{
if(secv==p) ///exista sanse ca patternul sa se potriveasca
{
if(potrivire(i))
{
nrpoz++;
poz[nrpoz]=i;
}
}
///faci trecerea de la hashul secv curente la hashul secv urmatoare
secv=(secv-sir[i]*maxi+ d*q )%q;
secv=(secv*d+sir[i+m])%q;
}
}
void afisare()
{
int32_t i;
f2<<nrpoz<<"\n";
for(i=1; i<=nrpoz; i++)
f2<<poz[i]<<" ";
}
int main()
{
f1>>pa>>sir;
m=strlen(pa);
n=strlen(sir);
maxi=maxim();///= d^(m-1)%q
pattern_primasecv();
rabin_karp();
afisare();
return 0;
}