Cod sursa(job #345985)

Utilizator ancaaaancaaa ancaaa Data 6 septembrie 2009 00:03:18
Problema Potrivirea sirurilor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.96 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 666017

// un numar prim foarte mare
#define modHash2 2000003

// 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);

	printf("%s\n", P);
	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;

//printf("%d\n", m);	
	// 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+T[i])%modHash1, h2=(h2*D+T[i])%modHash2;
	
	for (int i=m-1; i<n; i++) {
		// adaug cifra
		h1=(h1*D+T[i])%modHash1;
		h2=(h2*D+T[i])%modHash2; 

		if (h1==h1P && h2==h2P)
		{
		    if(nrsol < 1000)
			sol[++nrsol] = i-m+1;
		    else ++nrsol;
		}	
		// scad cifra
		//printf("%d %d\n", i-m ,i);

		h1-= (T[i-m+1]*pow1D)%modHash1;
		h2-= (T[i-m+1]*pow2D)%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;
}