Cod sursa(job #1457206)

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

// !!! the MAXN number might be too big for 
// the stack of variables in main for local compilers
const int MAXN = 2000001; // max number of chars
const int base = 256; // number of characters 
// to avoid collisions, the hash is calculated 2x
// by using 2 different prime numbers for modulo
const int mod_prime1 = 100007; // big-enough prime number
const int mod_prime2 = 100021; // big-enough prime number

int main()
{
	// INPUT
    ifstream indata("strmatch.in");
    char A[MAXN], B[MAXN];
     
    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 baseToPow1 = 1, baseToPow2 = 1;
	int hashA1 = 0, hashA2 = 0;
	int hashB_last1 = 0, hashB_last2 = 0;
	
    for (int i = 0; i < m; i++) {
		hashA1 = (hashA1 * base + A[i]) % mod_prime1;
		hashA2 = (hashA2 * base + A[i]) % mod_prime2;
		
		hashB_last1 = (hashB_last1 * base + B[i]) % mod_prime1;
		hashB_last2 = (hashB_last2 * base + B[i]) % mod_prime2;
		
		if (i != 0) {
			baseToPow1 = (baseToPow1 * base) % mod_prime1;
			baseToPow2 = (baseToPow2 * base) % mod_prime2;
		}
    }
	
	 
	if (hashB_last1 == hashA1 && hashB_last2 == hashA2) {
			positions.push_back(0);
	}
 
	// check that the hashes match
    for (int i = m; i < n; i++)
    {
		hashB_last1 = ((hashB_last1 - (B[i - m] * baseToPow1) % mod_prime1 + mod_prime1) * base + B[i]) % mod_prime1;
		hashB_last2 = ((hashB_last2 - (B[i - m] * baseToPow2) % mod_prime2 + mod_prime2) * base + B[i]) % mod_prime2;
	
		if (hashB_last1 == hashA1 && hashB_last2 == hashA2) {
			positions.push_back(i - m + 1);
		}
	}

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