Cod sursa(job #1570691)

Utilizator alexandru92alexandru alexandru92 Data 16 ianuarie 2016 19:11:13
Problema Potrivirea sirurilor Scor 36
Compilator cpp Status done
Runda Arhiva educationala Marime 2.26 kb
#include <fstream>
#include <array>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
#include <limits>
#include <iostream>

using std::string;
using std::vector;
using std::pair;
using std::array;

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

using BadCharTable = array<vector<int>, std::numeric_limits<char>::max()>;

BadCharTable buildBadCharTable(const string& p) {
    BadCharTable t;

    for (size_t i = 0; i < p.size(); ++i) {
        t[p[i]].push_back(i);
    }

    return t;
}

int computeBadCharShift(const pair<char, int>& x, const BadCharTable& t) {
    const auto& v = t[x.first];
    if (v.empty()) {
        return x.second;
    }
    else if (v.size() <= 15) {
        for (int i = v.size() - 1; i >= 0; --i) {
            if (v[i] < x.second) {
                return x.second - v[i];
            }
        }
        return x.second;
    }
    else {
        auto it = std::lower_bound(v.begin(), v.end(), x.second);
        return x.second - (it == v.begin() ? 0 : *(it - 1));
    }
}

pair<int, vector<int>> strMatch(const string& p, const  string& s) {
    if (p.size() > s.size()) {
        return std::make_pair(0, vector<int>{});
    }
    else if (p.size() == s.size()) {
        return p != s ? std::make_pair(0, vector<int>{}) : std::make_pair(1, vector<int>{0});
    }

    BadCharTable badCharTable = buildBadCharTable(p);

    int numMatches = 0, skip = 0;
    vector<int> matches;

    matches.reserve(NUM_OF_MAX_MATCHES_TO_SHOW);
    for (size_t i = p.size() - 1; i < s.size(); i += skip) {
        int k = i, j = p.size() - 1;
        for (; j >= 0 && s[k] == p[j]; --k, --j);

        if (j < 0) {
            skip = 1;
            ++numMatches;
            if (numMatches <= matches.capacity()) {
                matches.push_back(k + 1);
            }
        }
        else {
            skip = computeBadCharShift({s[i], j}, badCharTable);
        }
    }

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


int main() {
    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, " "});
    out << '\n';

    return 0;
}