Cod sursa(job #1968810)

Utilizator Laura_CorneiLaura Maria Cornei Laura_Cornei Data 17 aprilie 2017 21:28:53
Problema Potrivirea sirurilor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 2.07 kb
#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;
}