Pagini recente » Cod sursa (job #3182138) | Cod sursa (job #2945669) | Cod sursa (job #380849) | Cod sursa (job #1500912) | Cod sursa (job #1570691)
#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;
}