Cod sursa(job #1748080)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 26 august 2016 05:37:28
Problema Potrivirea sirurilor Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 1.7 kb
#include <bits/stdc++.h>
using namespace std;

using sit = string::iterator;

pair<int, int> find_self_maximal_prefix_and_period(sit str, const int n){
	int period = 1;
	for(int i = 1; i < n; ++i){
		if(str[i] < str[i-period]){
			period = i+1; }
		else if(str[i] > str[i-period]){
			return make_pair(i, period); } }
	return make_pair(n, period); }

int find_self_maximal_period(sit str, const int n){
	int j = 0;
	while(j < n){
		auto p = find_self_maximal_prefix_and_period(str+j, n-j);
		if(j+p.first >= n-1) return j;
		else j += p.first - (p.first % p.second); } }

template <typename Callback>
void find_all_self_maximal(sit str, const int n, sit pat, const int m, Callback& cb){
	int i = 0, j = 0, period = 1;
	while(i <= n-m){
		while(j < m && pat[j] == str[i+j]){
			++j;
			if(j > period && pat[j-1] != pat[j-period-1]){
				period = j; } }
		if(j == m+1){
			break; }
		if(j == m){
			cb(i); }
		i += period;
		if(j+1 >= 2 * period) j -= period;
		else j = 0, period = 1; } }

int main(){
	ifstream f("strmatch.in");
	ofstream g("strmatch.out");
	string str, pat;

	f >> pat >> str;

	int nr_match = 0, prev = -1;

	const int su = find_self_maximal_period(begin(pat), pat.size()), sv = pat.size() - su;
	auto cb1 = [&](const int i){
		if(i - prev > su && equal(begin(pat), begin(pat) + su, begin(str) + i - su)){
			++nr_match; } };

	find_all_self_maximal(begin(str), str.size(), begin(pat) + su, sv, cb1);

	g << nr_match << endl;

	nr_match = 0;
	prev = -1;
	auto cb2 = [&](const int i){
		if(i - prev > su && equal(begin(pat), begin(pat) + su, begin(str) + i - su)){
			prev = i-1;
			if(nr_match++ < 1000){
				g << i-su << ' '; } } };

	find_all_self_maximal(begin(str), str.size(), begin(pat) + su, sv, cb2);

	return 0; }