Cod sursa(job #2976720)

Utilizator TudosieRazvanTudosie Marius-Razvan TudosieRazvan Data 9 februarie 2023 21:42:50
Problema Potrivirea sirurilor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2 kb
#include <fstream>
#include <climits>
#include <vector>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <bitset>
#include <map>
#include <cstring>
#include <algorithm>

//Algoritmul Rabin-Karp
//Complexitate O(n+m)


#define NMAX 2000003
#define BAZA 73

#define MOD1 66601
#define MOD2 66701

using namespace std;


FILE* fin, * fout;

int n;
char A[NMAX], B[NMAX];
int match[NMAX];//pozitiile din B in care am gasit match

int main()
{
	fin = fopen("strmatch.in", "r");
	fout = fopen("strmatch.out", "w");


	fscanf(fin, "%s %s", A, B);
	int n = strlen(A);
	int m = strlen(B);

	if (n > m)
	{
		fprintf(fout, "0\n");
		return 0;
	}

	int P1 = 1, P2 = 1;//ca sa gasim repede baza la puterea n in functie de modulele specificate(pentru precalcularea )
	int hashA1 = 0, hashA2 = 0;//hash-urile pentru baze in functie de modul
	for (int i = 0; i < n; i++)
	{
		hashA1 = (hashA1 * BAZA + A[i]) % MOD1;
		hashA2 = (hashA2 * BAZA + A[i]) % MOD2;

		if (i != 0)
		{
			P1 = (P1 * BAZA) % MOD1;
			P2 = (P2 * BAZA) % MOD2;
		}
	}

	//fac acelasi lucru si pentru sirul B
	int hashB1 = 0, hashB2 = 0;
	for (int i = 0; i < n; i++)
	{
		hashB1 = (hashB1 * BAZA + B[i]) % MOD1;
		hashB2 = (hashB2 * BAZA + B[i]) % MOD2;
	}
	//verific primul caz de egalitate
	int matches = 0;
	if (hashA1 == hashB1 && hashA2 == hashB2)
	{
		match[0] = 1;
		matches++;
	}

	//incep sa imi formez urmatorul sir
	for (int i = n; i < m; i++)
	{
		//scad primul element din hash si adaug urmatorul element
		hashB1 = ((hashB1 - (B[i - n] * P1) % MOD1 + MOD1) * BAZA + B[i]) % MOD1;
		hashB2 = ((hashB2 - (B[i - n] * P2) % MOD2 + MOD2) * BAZA + B[i]) % MOD2;

		if (hashB1 == hashA1 && hashB2 == hashA2) {
			match[i - n + 1] = 1; 
			matches++;
		}
	}
	fprintf(fout, "%d\n", matches);

	//afisez primele 1000 de match-uri
	int k = 0;
	for (int i = 0; i < m && k < 1000; i++) {
		if (match[i]) {
			fprintf(fout, "%d ", i);
			k++;
		}
	}

	return 0;
}