Cod sursa(job #1748082)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 26 august 2016 06:25:15
Problema Potrivirea sirurilor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.93 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){
            cb(i); }
        i += period;
        if(j >= 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)){
            prev = i;
            ++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;
            if(nr_match++ < 1000){
                g << i-su << ' '; } } };
 
    find_all_self_maximal(begin(str), str.size(), begin(pat) + su, sv, cb2);
 
    return 0; }