Cod sursa(job #345977)

Utilizator ancaaaancaaa ancaaa Data 5 septembrie 2009 23:25:51
Problema Potrivirea sirurilor Scor 14
Compilator cpp Status done
Runda Arhiva educationala Marime 1.98 kb
                                                                     
                                                                     
                                                                     
                                             
/*
	Algoritmul Rabin-Karp in complexitate O(n+m).
*/

#include <iostream>
//#include <conio.h>
#include <cstring>

using namespace std;

// dimensiunea maxima a textului
#define N 2000002

// dimensiunea maxima a modelului
#define M 2000002

// baza in care se lucreaza este 255
#define D 255

// un numar prim foarte mare
#define modHash1 100007

// un numar prim foarte mare
#define modHash2 100021

// textul
char *T;

// modelul
char *P;

// dimensiunea textului
int n;

// dimensiunea modelului
int m;

int sol[1024];
int nrsol;

int main() {
	int h1P=0, h2P=0, h1=0, h2=0;

	T=new char[N];
	P=new char[M];
	
	for(int i = 0 ; i < N; ++i) T[i] = 0;
	for(int i = 0; i < M; ++i) P[i] = 0;

	freopen("strmatch.in","r",stdin);
	gets(P);
	gets(T);

	n=strlen(T);
	m=strlen(P);

	int pow1D=D%modHash1;
	int pow2D=D%modHash2;
	for (int i=2; i<=m-1; i++)
		pow1D=(pow1D*D)%modHash1, pow2D=(pow2D*D)%modHash2;
	
	// calculam hash-ul modelului
	for (int i=0; i<m; i++)
		h1P=(h1P*D+P[i])%modHash1, h2P=(h2P*D+P[i])%modHash2;

	// calculam 2 hash-uri pentru prima secventa m-1 a textului
	for (int i=0; i<m-1; i++)
		h1=((h1*D)%modHash1+T[i]%modHash1)%modHash1, h2=((h2*D)%modHash2+T[i]%modHash2)%modHash2;
	
	for (int i=m-1; i<n; i++) {
		// adaug cifra
		h1=((h1*D)%modHash1+T[i]%modHash1)%modHash1;
		h2=((h2*D)%modHash2+T[i]%modHash2)%modHash2; 

		if (h1==h1P && h2==h2P)
		{
		    if(nrsol < 1000)
			sol[++nrsol] = i-m;
		    else ++nrsol;
		}	
		// scad cifra
		h1-= (T[i-m+1]*pow1D%modHash1)%modHash1;
		h2-= (T[i-m+1]*pow2D%modHash2)%modHash2;

		while (h1<0) h1+=modHash1;
		while (h2<0) h2+=modHash2;
	}

//	getch();

	freopen("strmatch.out","w",stdout);

	printf("%d\n", nrsol);
	for(int i = 1; i <= min(nrsol, 1000); ++i)
	    printf("%d ", sol[i]);

	return 0;
}