Pagini recente » Cod sursa (job #1014238) | Cod sursa (job #2803535) | Cod sursa (job #802233) | Cod sursa (job #807785) | Cod sursa (job #3303801)
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <array>
#include <cassert>
using namespace std;
constexpr int P = 256; // Number of characters in the input (ASCII)
inline constexpr std::array<int, 2> kPrimeMods = {1000003, 1000033};
int computePatternHash(const string &pattern, int mod)
{
int hash = 0;
for (char c : pattern)
{
hash = (hash * P + (c)) % mod;
}
return hash;
}
void findPatternOccurrences(const string &text, const string &pattern, vector<int> &result)
{
int patternLength = pattern.size();
int textLength = text.size();
if (patternLength > textLength)
return;
vector<int> textHashes(kPrimeMods.size());
vector<int> patternHashes(kPrimeMods.size());
for (size_t i = 0; i < kPrimeMods.size(); ++i)
{
for (int j = 0; j < patternLength; ++j)
{
textHashes[i] = (textHashes[i] * P + (text[j])) % kPrimeMods[i];
}
patternHashes[i] = computePatternHash(pattern, kPrimeMods[i]);
}
array<int, 2> maxPower = {1, 1};
for (size_t i = 0; i < kPrimeMods.size(); ++i)
{
for (int j = 0; j < patternLength - 1; ++j)
{
maxPower[i] = (maxPower[i] * P) % kPrimeMods[i];
}
}
for (size_t i = 0; i < textLength - patternLength + 1;)
{
bool match = true;
for (size_t j = 0; j < kPrimeMods.size(); ++j)
{
if (textHashes[j] != patternHashes[j])
{
match = false;
break;
}
}
if (match)
{
assert(i + patternLength <= textLength);
if (text.substr(i, patternLength) == pattern)
{
result.push_back(i);
}
}
i++;
if (i < textLength - patternLength + 1)
{
for (size_t j = 0; j < kPrimeMods.size(); ++j)
{
long long h = textHashes[j] - 1LL * (text[i - 1]) * maxPower[j];
h = ((h % kPrimeMods[j]) + kPrimeMods[j]) % kPrimeMods[j] * P + (text[i + patternLength - 1]);
textHashes[j] = h % kPrimeMods[j];
}
}
}
}
int main()
{
ifstream fin("strmatch.in");
ofstream fout("strmatch.out");
string x, y;
fin >> x >> y;
if (x.size() > y.size())
{
fout << 0 << '\n';
return 0;
}
vector<int> result;
findPatternOccurrences(y, x, result);
fout << result.size() << '\n';
for (size_t i = 0; i < result.size() && i < 1000; ++i)
{
fout << result[i] << ' ';
}
}