Cod sursa(job #1457143)

Utilizator tony.hegyesAntonius Cezar Hegyes tony.hegyes Data 2 iulie 2015 19:40:19
Problema Potrivirea sirurilor Scor 14
Compilator cpp Status done
Runda Arhiva educationala Marime 1.27 kb
#include <fstream>
#include <vector>
#include <cmath>
#include <cstring>
using namespace std;

#define base 256 // number of characters 
#define mod_prime 179422921 // big-enough prime number

int main(int argc, char **argv)
{
	// INPUT
	ifstream indata("strmatch.in");
	char A[2000001], B[2000001];
	
	indata >> A >> B;
	indata.close();
	
	// PATTERN MATCHING
	vector<int> positions;
	int m = strlen(A), n = strlen(B);
	
	// calculate hash for pattern
	// and for first substring
	int baseToPow = 1;
	int hashA = 0, hashB_last = 0;
	for (int i = 0; i < m; i++) {
		baseToPow *= base;
		hashA = (hashA * base + A[i]) % mod_prime;
		hashB_last = (hashB_last * base + B[i]) % mod_prime;
	}
	baseToPow /= base;
	
	// check that the hashes match
	for (int i = 0; i + m <= n; i++) {
		if (hashA == hashB_last) {
			// make sure it's not a collision
			int q = 0;
			while(A[q] == B[i + q]) {
				q++;
			}
			if (q == m) {
				// it's not a collision
				positions.push_back(i);
			}
		}
		
		hashB_last = abs(((hashB_last - B[i] * baseToPow) * base 
						+ B[i + m]) % mod_prime);
	}
	
	// OUTPUT
	ofstream outdata("strmatch.out");
	outdata << positions.size() << "\n";
	for (size_t i = 0; i < positions.size() && i < 1000; i++) {
		outdata << positions[i] << " ";
	}
	outdata.close();
	return 0;
}