Cod sursa(job #1201645)

Utilizator vasile_pojogaPojoga Vasile vasile_pojoga Data 25 iunie 2014 16:59:58
Problema Potrivirea sirurilor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 2.36 kb
#include <fstream>
#include <string>
#include <vector>

using namespace std;

ifstream fin("strmatch.in");
ofstream fout("strmatch.out");

string T,P;
unsigned int nrSol;
vector<int> sol;

void getMatches(string& P, string& T, unsigned int d, unsigned int q1, unsigned int q2);
unsigned int pow(unsigned int d, unsigned int m, unsigned int q);
unsigned int getHash(string& S, unsigned int d, unsigned int q);
unsigned int getNextHash(string& T, unsigned int poz, unsigned int d, unsigned int q, unsigned int dM, unsigned int m, unsigned int prevH);
void print();

int main()
{
	fin>>P>>T;
	getMatches(P,T,73,100021,100007);
	print();
	return 0;
}

void getMatches(string& P, string& T, unsigned int d, unsigned int q1, unsigned int q2)
{
	unsigned int m = P.length();
	unsigned int n = T.length();
	unsigned int dM1 = pow(d, m-1, q1); //(d^(m-1))%q
	unsigned int dM2 = pow(d, m-1, q2); //(d^(m-1))%q
	unsigned int Ph1 = getHash(P, d, q1); //pattern H1
	unsigned int Ph2 = getHash(P, d, q2); //pattern H2
	string temp = T.substr(0,m);
	unsigned int Th1 = getHash(temp, d, q1);
	unsigned int Th2 = getHash(temp, d, q2);
	nrSol = 0;
	sol.clear();
	if(Ph1 == Th1 && Ph2 == Th2)
	{
		nrSol++;
		sol.push_back(0);
	}
	for(unsigned int i=m; i<n; i++)
	{
		Th1 = getNextHash(T,i,d,q1,dM1,m,Th1);
		Th2 = getNextHash(T,i,d,q2,dM2,m,Th2);
		if(Ph1 == Th1 && Ph2 == Th2)
		{
			nrSol++;
			sol.push_back(i-m+1);
		}		
	}
}

unsigned int getHash(string& S, unsigned int d, unsigned int q)
{
	unsigned int hash = S[0];
	for(unsigned int i=1; i<S.length(); i++)
	{
		hash = (hash * d + S[i]) % q;
	}
	return hash;
}

unsigned int getNextHash(string& T, unsigned int poz, unsigned int d, unsigned int q, unsigned int dM, unsigned int m, unsigned int prevH)
{
	unsigned int hash = prevH;
	hash = (hash + q) - ((T[poz-m]*dM) % q); //removed previous
	hash = (hash * d + T[poz]) % q; //shifted with 1 position to left and added last value to hash
	//hash = (hash + T[poz]) % q; added last value to hash
	return hash;
}

unsigned int pow(unsigned int d, unsigned int m, unsigned int q)
{
	unsigned int result = 1;
	for(unsigned int i=1; i<=m; i++)
	{
		result = (result * d) % q;
	}
	return result;
}

void print()
{
	fout<<nrSol<<'\n';
	if(nrSol > 1000) nrSol = 1000;
	for(unsigned int i = 0; i < sol.size(); i++)
	{
		fout<<sol[i]<<' ';
	}
}