Cod sursa(job #2217417)

Utilizator nurof3nCioc Alex-Andrei nurof3n Data 30 iunie 2018 13:13:13
Problema Potrivirea sirurilor Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 1.99 kb
#include <fstream>

using namespace std;

ifstream in("strmatch.in");
ofstream out("strmatch.out");

const int DIM = 2000001, MOD1 = 100007, MOD2 = 100021, MOD3 = 100003, B = 73;
char text[DIM], pattern[DIM];
int T, P, nrap, ap[1001];
int hashP1, hashP2, hashP3, hashT1, hashT2, hashT3; //triple hashing: daca cele 3 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, B3 = 1; //reprezinta B ^ (P - 1)
    for(int i = 0; i < P; i++)
    {
        hashP1 = h(hashP1, pattern[i], MOD1);
        hashP2 = h(hashP2, pattern[i], MOD2);
        hashP3 = h(hashP3, pattern[i], MOD3);
        if(i)
        {
            B1 = h(B1, 0, MOD1);
            B2 = h(B2, 0, MOD2);
            B3 = h(B3, 0, MOD3);
        }
    }

    for(int i = 0; i < P; i++)
    {
        hashT1 = h(hashT1, text[i], MOD1);
        hashT2 = h(hashT2, text[i], MOD2);
        hashT3 = h(hashT3, text[i], MOD3);
    }
    if(hashT1 == hashP1 && hashT2 == hashP2 && hashT3 == hashP3)
        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);
        hashT3 = h((hashT3 - text[i - P] * B3) % MOD3 + MOD3, text[i], MOD3);
        if(hashT1 == hashP1 && hashT2 == hashP2 && hashT3 == hashP3)
            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;
}