Cod sursa(job #2493855)

Utilizator savigunFeleaga Dragos-George savigun Data 17 noiembrie 2019 02:50:14
Problema Potrivirea sirurilor Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.54 kb
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;

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

#define B 73
#define mod1 10000019
#define mod2 100021

vector<int> rabin_karp(string& str, string& pattern) {
	if (pattern.length() > str.length()) return {};
	if (pattern.length() == 0) return {};

	vector<int> matches;

	// hash for pattern
	int ph1 = pattern[0];
	int ph2 = ph1;
	int P1 = 1;
	int P2 = 1;

	for (int i = 1; i < pattern.length(); ++i) {
		ph1 = ((ph1 * B) % mod1 + (pattern[i])) % mod1;
		ph2 = ((ph2 * B) % mod2 + (pattern[i])) % mod2;
		P1 = (P1 * B) % mod1;
		P2 = (P2 * B) % mod2;
	}

	// hash for string
	int sh1 = str[0];
	int sh2 = sh1;

	for (int i = 1; i < pattern.length(); ++i) {
		sh1 = (sh1 * B + str[i]) % mod1;
		sh2 = (sh2 * B + str[i]) % mod2;
	}

	if (ph1 == sh1) matches.push_back(0);

	for (int i = pattern.length(); i < str.length(); ++i) {
		sh1 = ((sh1 - (str[i - pattern.length()] * P1) % mod1 + mod1) * B + str[i]) % mod1;
		sh2 = ((sh2 - (str[i - pattern.length()] * P2) % mod2 + mod2) * B + str[i]) % mod2;
		if (ph1 == sh1) matches.push_back(i - pattern.length() + 1);
	}

	return matches;
}

int main() {
	string pattern;
	string str;

	fin >> pattern;
	fin >> str;

	vector<int> matches = rabin_karp(str, pattern);
	vector<int> sol = vector<int>(matches.begin(), matches.begin() + min(1000, (int)matches.size()));
	
	fout << matches.size() << '\n';
	for (int i : sol) {
		fout << i << ' ';
	}

	return 0;
}