Cod sursa(job #2265740)

Utilizator preda.andreiPreda Andrei preda.andrei Data 21 octombrie 2018 17:18:37
Problema Potrivirea sirurilor Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.67 kb
#include <fstream>
#include <string>
#include <vector>

using namespace std;

constexpr int kMaxMatches = 1000;

int FindMatchLen(const string &str, size_t right, size_t left = 0)
{
    auto len = 0;
    while (right + len < str.size() && str[len + left] == str[len + right]) {
        len += 1;
    }
    return len;
}

pair<int, vector<int>> FindMatches(const string &pattern, const string &text)
{
    string str(pattern);
    str += text;

    vector<int> matches;
    auto match_count = 0;

    vector<size_t> z(str.size());
    size_t left = 0, right = 0;

    for (size_t i = 1; i < str.size(); i += 1) {
        if (i >= right) {
            z[i] = FindMatchLen(str, i);
            left = i;
            right = i + z[i] - 1;
        } else {
            auto other = i - left;
            left = i;
            if (i + z[other] <= right) {
                z[i] = z[other];
            } else {
                auto matched = right - i;
                z[i] = matched + 1 + FindMatchLen(str, right + 1, other + matched);
                right = i + z[i] - 1;
            }
        }

        if (i >= pattern.size() && z[i] >= pattern.size()) {
            match_count += 1;
            if (match_count <= kMaxMatches) {
                matches.push_back(i - pattern.size());
            }
        }
    }

    return {match_count, matches};
}

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

    string pattern, text;
    getline(fin, pattern);
    getline(fin, text);

    auto matches = FindMatches(pattern, text);
    fout << matches.first << "\n";

    for (const auto &pos : matches.second) {
        fout << pos << " ";
    }
    fout << "\n";

    return 0;
}