Cod sursa(job #2036916)

Utilizator SlevySlevoaca Stefan-Gabriel Slevy Data 11 octombrie 2017 13:25:19
Problema Potrivirea sirurilor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.96 kb
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <unordered_map>
#define MOD 666013
#define base 7
#define LIM 1000

using namespace std;

void gcd(int a, int b, int& x, int& y) {

	if (b == 0) {

		x = 1;
		y = 0;
		return;
	}
	else {

		gcd(b, a % b, x, y);
		int aux = x;
		x = y;
		y = aux - (a / b) * y;
	}
}

string A, B;
int inv_mod;
vector<int> pos;
unordered_map<char, int> asoc;

void initialize() {

	int y;
	gcd(base, MOD, inv_mod, y);
	if (inv_mod < 0)
		inv_mod = MOD + inv_mod % MOD;

	ifstream in("strmatch.in");
	getline(in, A);
	getline(in, B);
	in.close();

	int nr = -1;
	for (char i = 'a'; i <= 'z'; i++)
		asoc.insert(make_pair(i, ++nr));
	for (char i = 'A'; i <= 'Z'; i++)
		asoc.insert(make_pair(i, ++nr));
	for (char i = '0'; i <= '9'; i++)
		asoc.insert(make_pair(i, ++nr));
}

int main() {

	initialize();

	unsigned int k = A.length();
	unsigned int pow = 1;
	unsigned int hash_value = 0;
	unsigned int search_hash = 0;
	unsigned int nr_occ = 0;
	bool ok = true;

	for (unsigned int i = 0; i < k; i++) {

		hash_value = (hash_value + (asoc[B[i]] * pow) % MOD) % MOD;
		search_hash = (search_hash + (asoc[A[i]] * pow) % MOD) % MOD;
		if (i != k - 1)
			pow = (pow * base) % MOD;
		if (A[i] != B[i])
			ok = false;
	}

	if (ok) {

		nr_occ++;
		pos.push_back(0);
	}

	for (unsigned int i = k; i < B.size(); i++) {

		hash_value = (((hash_value - asoc[B[i - k]]) * 1LL * inv_mod) % MOD + asoc[B[i]] * 1LL * pow) % MOD;

		if (hash_value == search_hash) {

			ok = true;
			for (unsigned int j = i - k + 1; j <= i; j++)
				if (B[j] != A[j - i + k - 1]) {

					ok = false;
					break;
				}
			if (ok) {
				nr_occ++;
				if (pos.size() < LIM)
					pos.push_back(i - k + 1);
			}
		}
	}

	ofstream out("strmatch.out");
	out << nr_occ << "\n";
	for (unsigned int i = 0; i < pos.size(); i++)
		out << pos[i] << " ";
	out.close();
	return 0;
}