Cod sursa(job #2273348)

Utilizator cezar.plescaCezar Plesca cezar.plesca Data 31 octombrie 2018 14:17:11
Problema Potrivirea sirurilor Scor 80
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.58 kb
#include<stdio.h>
#include<string.h>

char cuv[2000001];
char sir[2000001];

int nb;
int poz[2000000];

int base=257;
//int p=10007;
int p;
int bits=16;
int mask;

void rabinkarp(char* pattern, int m, char* text, int n){
	
	int hp=0, B=1, H=0;
	int bpower=1;

	/*
	for(int i=0;i<m;i++){
		hp=(hp*base+pattern[i])%p; // actualizarea progresiva a codului	
		H=(H*base+text[i])%p; // actualizarea progresiva a codului
		B=bpower;
		bpower=(bpower*base)%p; // calculul puterilor lui b
	}
	*/

	for(int i=0;i<m;i++){
		hp=(hp*base+pattern[i]) & mask; // actualizarea progresiva a codului	
		H=(H*base+text[i]) & mask ; // actualizarea progresiva a codului
		B=bpower;
		bpower=(bpower*base) & mask; // calculul puterilor lui b
	}

	int j,aux;
	for(int i=0;i<=n-m;i++){ // potrivire pe pozitia i
		if(H==hp){
			for(j=0;j<m;j++){ // comparatia cu patternul
				if(text[i+j]!=pattern[j])
					break;
			}
			if(j==m){
				nb++;
				if(nb<=1000)
					poz[nb-1]=i;
			}
		}
		if(i<n-m){
			aux=base*(H-text[i]*B)+text[m+i];
			if(aux<0){
				H = p - ((-aux) & mask); 
			}
			else{
				H =aux & mask;
			}
		}
	}
}

int main(){

	p=1<<bits;
	mask=p-1;

	FILE* f= fopen("strmatch.in","rt");
	FILE* g= fopen("strmatch.out","wt");
	
	fscanf(f,"%s",cuv);
	fscanf(f,"%s",sir);

	int m=strlen(cuv);
	int n=strlen(sir);

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

	rabinkarp(cuv,m,sir,n);

	fprintf(g,"%d\n",nb);
	for(int i=0;i<nb;i++){
		if(i<1000)
			fprintf(g,"%d ",poz[i]);	
		else
			break;
	}

	fclose(g);
	fclose(f);
	return 0;
}