Pagini recente » Cod sursa (job #683656) | Cod sursa (job #2880079) | Cod sursa (job #787064) | Cod sursa (job #2101428) | Cod sursa (job #1570643)
#include <fstream>
#include <array>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
#include <limits>
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()>;
vector<int> ZAlgo(const string& p) {
vector<int> Z(p.size(), 0);
Z[0] = p.size();
for (int k = 1, lt = 0, rt = 0; k < p.size(); ++k) {
if (k > rt) {
int i;
for (i = 0; i + k < p.size() && p[i] == p[i + k]; ++i);
Z[k] = i;
if (i) {
lt = k;
rt = i + k - 1;
}
}
else {
if (Z[k - lt] < rt - k + 1) {
Z[k] = Z[k - lt];
}
else {
int i;
for (i = rt + 1; i < p.size() && p[i] == p[i - k]; ++i);
Z[k] = i - k;
lt = k;
rt = i - 1;
}
}
}
return Z;
}
BadCharTable buildBadCharTable(const string& p) {
BadCharTable t;
for (int i = 0; i < p.size(); ++i) {
t[p[i]].push_back(i);
}
return t;
}
int computeBadCharShift(const pair<char, int>& x, const BadCharTable& t) {
if (t[x.first].empty()) {
return 0;
}
else if (t[x.first].size() <= 15) {
for (int i = t[x.first].size() - 1; i >= 0; --i) {
int j = t[x.first][i];
if (j < x.second) {
return j + 1;
}
}
return 0;
}
else {
const auto& it = std::lower_bound(t[x.first].begin(), t[x.first].end(), x.second);
return it == t[x.first].end() || it == t[x.first].begin() ? 0 : *(it - 1) + 1;
}
}
pair<int, vector<int>> strMatch(const string& p, const string& s) {
BadCharTable badCharTable = buildBadCharTable(p);
int numMatches = 0, skip = 0;
vector<int> matches;
matches.reserve(std::max<int>(s.size() - p.size() + 1, NUM_OF_MAX_MATCHES_TO_SHOW));
for (int i = p.size(); 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 = p.size() - 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, " "});
return 0;
}