Cod sursa(job #2207332)

Utilizator dragomir_ioanDragomir Ioan dragomir_ioan Data 25 mai 2018 15:30:01
Problema Potrivirea sirurilor Scor 38
Compilator c Status done
Runda Arhiva educationala Marime 2.21 kb

#include <stdio.h>
#include <string.h>

#define M1 666013
#define M2 1000003

//int lookup['z'+1];

char mare[2000001], mic[2000001];

int rezultate[1000], cate;

inline int lookup(char c) {
	if(c <= '9') return c - '0';
	if(c <= 'Z') return c - 'A' + 10;
	return c - 'a' + 36;
}

int main() {
	FILE *fin = fopen("strmatch.in", "r");

	fgets(mic, 2000001, fin);
	fgets(mare, 2000001, fin);

	mic[strcspn(mic, "\r\n")] = 0;
	mare[strcspn(mare, "\r\n")] = 0;

	int l_mic = strlen(mic);
	int l_mare = strlen(mare);
	fclose(fin);

/*	{
		int k = 0;
		for(int i='0'; i<='9'; i++) lookup[i] = k++;
		for(int i='A'; i<='Z'; i++) lookup[i] = k++;
		for(int i='a'; i<='z'; i++) lookup[i] = k++;
	}
*/

	int hash1 = 0, hash2 = 0,			// hashurile bucatii mici
		puterea1 = 1, puterea2 = 1,		// 62 la puterea l_mic-1
		rolling1 = 0, rolling2 = 0;		// hashurile secventelor din aia mare

	for(int i=0; i<l_mic; i++) {
		//printf("hash1 = %d -> %c = %d -> ", hash1, mic[i], lookup(mic[i]));
		hash1 = (hash1 * 62 + lookup(mic[i])) % M1;
		//printf("%d\n", hash1);
		hash2 = (hash2 * 62 + lookup(mic[i])) % M2;

		rolling1 = (rolling1 * 62 + lookup(mare[i])) % M1;
		rolling2 = (rolling2 * 62 + lookup(mare[i])) % M2;

		if(i != 0) {	// sa sarim _un singur_ pas
			puterea1 = puterea1 * 62 % M1;
			puterea2 = puterea2 * 62 % M2;
		}
	}

	//printf("%d %d\n\n", hash1, hash2);

	for(int i=l_mic; i<l_mare; i++) {
		//printf("%d %d\n", rolling1, rolling2);
		if(hash1 == rolling1 && hash2 == rolling2) {
			if(cate < 1000) rezultate[cate] = i-l_mic;
			cate++;
		}


		//printf("rolling1 = %d -> %c = %d -> ", rolling1, mare[i-l_mic], lookup(mare[i-l_mic]));
		rolling1 = rolling1 - lookup(mare[i-l_mic]) * puterea1;	// scoate primul caracter
		
		while(rolling1 < 0) rolling1 += M1;						// make sure ca nu suntem pe negative
		rolling1 = (rolling1 * 62 + lookup(mare[i])) % M1;	// baga-l pe urmatorul

		//printf("%d\n", rolling1);

		rolling2 = rolling2 - lookup(mare[i-l_mic]) * puterea2;
		while(rolling2 < 0) rolling2 += M2;
		rolling2 = (rolling2 * 62 + lookup(mare[i])) % M2;
	}

	FILE *fout = fopen("strmatch.out", "w");
	fprintf(fout, "%d\n", cate);
	for(int i=0; i<cate; i++)
		fprintf(fout, "%d ", rezultate[i]);
	fprintf(fout, "\n");
	fclose(fout);

	return 0;
}