Cod sursa(job #686445)

Utilizator DSzprogDombi Szabolcs DSzprog Data 21 februarie 2012 17:00:33
Problema Potrivirea sirurilor Scor 12
Compilator cpp Status done
Runda Arhiva educationala Marime 1.39 kb
#include <cstdio>
#include <cstring>

char a[2000002], na;
char b[2000002], nb;
int c[1000];
int num;

class RKHash {
public:
	int hash;
	int f, m, s, p;
	void init(int fact, int mod, int size, char * str) {
		f = fact;
		m = mod;
		s = size;
		p = 1;
		hash = str[0];
		for (int i = 1; i < s; ++i) {
			hash = (hash * f + str[i]) % m;
			p *= fact;
			p %= mod;
		}
	}
	void feed(char add, char rem) {
		hash = (m + hash - (p * rem) % m) % m;
		hash = (hash * f + add) % m;
	}
};

class Hash {
public:
	RKHash a, b;
	Hash(int size, char * str) {
		a.init(71, 100007, size, str);
		b.init(71, 100021, size, str);
	}
	void feed(char add, char rem) {
		a.feed(add, rem);
		b.feed(add, rem);
	}
	bool operator == (Hash h) const {
		return(a.hash == h.a.hash && b.hash == h.b.hash);
	}
};

int main() {
	FILE * f1 = fopen("strmatch.in", "rt");
	fscanf(f1, "%s%s", a, b);
	na = strlen(a);
	nb = strlen(b);
	fclose(f1);

	if (nb >= na) {
		Hash ha(na, a);
		Hash hb(na, b);
		if (ha == hb) {
			c[num++] = 0;
		}
		for (int i = na; i < nb; ++i) {
			hb.feed(b[i], b[i - na]);
			if (ha == hb) {
				if (num < 1000) {
					c[num] = i - na;
				}
				++num;
			}
		}
	}

	FILE * f2 = fopen("strmatch.out", "wt");
	fprintf(f2, "%d\n", num);
	int dist = num < 1000 ? num : 1000;
	for (int i = 0; i < dist; ++i) {
		fprintf(f2, "%d ", c[i]);
	}
	fclose(f2);
}