Cod sursa(job #1562511)

Utilizator alexandru92alexandru alexandru92 Data 5 ianuarie 2016 10:49:29
Problema Potrivirea sirurilor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.66 kb
#include <fstream>
#include <string>
#include <array>
#include <vector>
#include <iterator>
#include <algorithm>
#include <iostream>


const int NMAX =  2000011;
const int NUM_OF_MAX_MATCHES_TO_SHOW = 1000;


std::array<int, NMAX * 2> Z;
std::pair<int, std::vector<int>> strMatch(const std::string& p, const std::string& s) {
    const std::string t {p + "$" + s};
    
    size_t lt = 0, rt = 0, numMatches =0;
    std::vector<int> matches;

    matches.reserve(NUM_OF_MAX_MATCHES_TO_SHOW);

    Z[0] = t.size();
    for (size_t k = 1; k < t.size(); ++k) {
        if (k > rt) {
            size_t i;
            for (i = 0; i + k < t.size() && t[i] == t[i + k]; ++i); 
            Z[k] = i;
            if (i) {
                lt = k;
                rt = i + k - 1;
            }
        }
        else {
            int p = k - lt;
            if (Z[p] < rt - k + 1) {
                Z[k] = Z[p];
            }
            else {
                size_t i;
                for (i = rt + 1; i < t.size() && t[i] == t[i - k]; ++i);
                Z[k] = i - k;
                lt = k;
                rt = i - 1;
            }
        }
        if (p.size() == Z[k]) {
            ++numMatches;
            if (NUM_OF_MAX_MATCHES_TO_SHOW > matches.size()) {
                matches.push_back(k - p.size() - 1);
            }
        }
    }

    return std::make_pair(numMatches, matches);
}

int main() {
    std::string p, s;
    std::ifstream in{"strmatch.in"};
    std::ofstream out{"strmatch.out"};

    in >> p >> s;
    const auto& x = strMatch(p, s);
    out << x.first << '\n';
    std::copy(x.second.begin(), x.second.end(), std::ostream_iterator<int>{out, " "});

    return 0;
}