Cod sursa(job #2875148)

Utilizator RobertuRobert Udrea Robertu Data 21 martie 2022 10:06:49
Problema Potrivirea sirurilor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.92 kb
/*
    Rezolvare problemei Strmatch folosinf algoritmul Rabin-Karp
    adaptat la litere mari si cifre
*/

#include <bits/stdc++.h>
#include <string>
#define prime1 100007
#define prime2 100021
using namespace std;

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

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int cnt = 0;
    vector<int> potriviri(1000);
    string text, pattern;
    fin >> pattern >> text;

    int i, j;
    int n = pattern.length(), m = text.length();
    int hash1 = 0, hash2 = 0, windowHash1 = 0, windowHash2 = 0;


/*
Atat pentru pattern, cat si pt prima fereastra, am calculat doua hash-uri.
Astfel, in for-ul mare unde mut fereastra de-a lungul textului, compar
doua hash-uri, si astfel scap de parcurgerea de verificare la fiecare potrivire.
*/

    for( i = 0; i < n; i++) {
        hash1 = (256 * hash1 + pattern[i]) % prime1; 
        hash2 = (256 * hash2 + pattern[i]) % prime2; 

        windowHash1 = (256 * windowHash1 + text[i]) % prime1; 
        windowHash2 = (256 * windowHash2 + text[i]) % prime2;
    }

/*
Aici am calculat baza(256 <=> nr de elemente din alfabet) la puterea (n - 1), folosita
pentru adaugarea noii litere la Rolling Hash.
*/

    int h = 1, w = 1;
    for(int i = 0; i < n - 1; i++)
        h = (h * 256) % prime1,
        w = (w * 256) % prime2;



    for(i = 0; i <= m - n; i++) {
        if( hash1 == windowHash1 && hash2 == windowHash2 ) {
            if( cnt <= 1000 ) 
                potriviri[cnt] = i;
            cnt++;
        }

        //Rolling Hash pt urmatoarea fereastra

        if( i < m - n ) {
            windowHash1 = (256*(windowHash1 - (text[i]*h) % prime1 + prime1) + text[i + n]) % prime1;
        
            windowHash2 = (256*(windowHash2 - (text[i]*w) % prime2 + prime2) + text[i + n]) % prime2;    
        }
    }

    fout << cnt << '\n';
 
    for(i = 0; i < min(1000, cnt); i++)
        fout << potriviri[i] << " ";

    return 0;
}