Pagini recente » Cod sursa (job #2446827) | Cod sursa (job #1070068) | Cod sursa (job #2330966) | Cod sursa (job #2953745) | Cod sursa (job #1258866)
#include <cmath>
#include <cstdint>
#include <fstream>
#include <string>
#include <utility>
#include <vector>
using namespace std;
constexpr uint64_t S1 = 1.140071482E19,
S2 = 7.600476546E18;
constexpr uint64_t BASE = 128;
inline uint64_t hash(const uint64_t key, const uint64_t s) {
return key * s;
}
uint64_t prehash(const string& s, const uint64_t base) {
uint64_t value = 0;
for (char c : s)
value = value * base + c;
return value;
}
class RollingPreHash {
string text;
uint64_t ph_value;
uint64_t ph_base, ph_base_pow_length;
size_t ph_length, pos;
public:
RollingPreHash(
const string& text,
const uint64_t base,
const uint64_t prehash_length) : text(text), ph_base(base),
ph_length(prehash_length),
ph_value(0), pos(0) {
if (pos + ph_length <= text.size()) {
ph_value = prehash(text.substr(0, ph_length), ph_base);
ph_base_pow_length = pow(ph_base, ph_length);
}
}
bool has_next() const { return pos + ph_length <= text.size(); }
pair<uint64_t, size_t> next() {
uint64_t result = ph_value;
size_t position = pos;
if (pos + ph_length < text.size()) {
ph_value = ph_value * ph_base - text[pos] * ph_base_pow_length + text[pos + ph_length];
pos += 1;
}
else if (pos + ph_length == text.size())
pos += 1;
return make_pair(result, position);
}
};
int main() {
ifstream fin("strmatch.in");
ofstream fout("strmatch.out");
string query, text;
fin >> query >> text;
const uint64_t HQ1 = ::hash(prehash(query, BASE), S1);
const uint64_t HQ2 = ::hash(prehash(query, BASE), S2);
size_t matches = 0;
vector<size_t> positions;
RollingPreHash rph(text, BASE, query.size());
while (rph.has_next()) {
pair<uint64_t, size_t> t = rph.next();
uint64_t& ph = t.first;
size_t& pos = t.second;
if (::hash(ph, S1) == HQ1 && ::hash(ph, S2) == HQ2) {
matches++;
if (matches <= 1000)
positions.push_back(pos);
}
}
fout << matches << '\n';
for (size_t p : positions) fout << p << ' ';
fout << endl;
return 0;
}