Cod sursa(job #2873226)

Utilizator RobertuRobert Udrea Robertu Data 18 martie 2022 22:02:23
Problema Potrivirea sirurilor Scor 16
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.01 kb
/*
Incercare de a scrie Rabin-Karp folosind hash
Mai exact cu Rolling Hash
*/

#include <bits/stdc++.h>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;

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

long prime = 7, rollingPow;
vector<int> potriviri;

long firstHash(string pattern);
long rollingHash(string text, int start, int finish, long oldHash);

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

    int i, j;
    int cnt = 0;
    string text, pattern;
    fin >> pattern >> text;

    int n = pattern.length();
    int m = text.length();
    long hash = firstHash(pattern);
    string firstWindow = text.substr(0, n);
    long windowHash = firstHash(firstWindow);

    for(i = 1; i + n - 1 < m; i++) {
        if(hash == windowHash) {
            for(j = 0; j < n; j++)
                if( pattern[j] != text[i + j - 1] )
                    break;
            if( j == n ) {
                if( cnt <= 1000 ) 
                    potriviri.push_back(i - 1);
                cnt++;
            }
        }

        windowHash = rollingHash(text, i, i + n - 1, windowHash);
    }

    if(hash == windowHash) {
        for(j = 0; j < n; j++)
            if( pattern[j] != text[i + j - 1] )
                break;
        if( j == n ) {
            if( cnt <= 1000 ) 
                potriviri.push_back(i - 1);
            cnt++;
        }
    }

    fout << cnt << '\n';

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

    return 0;
}

/*
Definitiile functiilor folosite in program
*/

long rollingHash(string text, int start, int finish, long oldHash) {
    long hash = (oldHash - (text[start - 1] - 'a' + 1)) / prime;
    hash += (text[finish] - 'a' + 1) * rollingPow;

    return hash;
}

long firstHash(string pattern) {
    long n = pattern.length(), power = 1;
    long hash = 0;

    for(int i = 0; i < n; i++) {
        hash += (pattern[i] - 'a' + 1) * power;
        power *= prime;
    }

    rollingPow = power / prime;

    return hash;
}