Cod sursa(job #1457191)

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

const int MAXN = 200001; // max number of chars
const int base = 256; // number of characters 
const int mod_prime = 100007; // 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 baseToPow = 1;
    int hashA = 0, hashB_last = 0;
    for (int i = 0; i < m; i++) {
		hashA = (hashA * base + A[i]) % mod_prime;
		hashB_last = (hashB_last * base + B[i]) % mod_prime;
		
		if (i != 0) {
			baseToPow = (baseToPow * base) % mod_prime;
		}
    }
 
	// check that the hashes match
    for (int i = m; i < n; i++)
    {
		if (hashB_last == hashA) {
            // make sure it's not a collision
            int q = 0;
            while(A[q] == B[i - m + q]) {
                q++;
            }
            if (q == m) {
                // it's not a collision
                positions.push_back(i - m);
            }
		}
        
		hashB_last = ((hashB_last - (B[i - m] * baseToPow) % mod_prime + mod_prime) * base + B[i]) % 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;
}