Pagini recente » Cod sursa (job #2968602) | Cod sursa (job #1591863) | Cod sursa (job #943015) | Cod sursa (job #392725) | Cod sursa (job #3303799)
#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 patterLength = pattern.size();
int textLength = text.size();
if (patterLength > 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 < patterLength; ++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 < patterLength - 1; ++j)
{
maxPower[i] = (maxPower[i] * P) % kPrimeMods[i];
}
}
int i = 0;
do
{
bool match = true;
for (size_t j = 0; j < kPrimeMods.size(); ++j)
{
if (textHashes[j] != patternHashes[j])
{
match = false;
break;
}
}
if (match)
{
assert(i + patterLength <= textLength);
if (text.substr(i, patterLength) == pattern)
{
result.push_back(i);
}
}
i++;
if (i < textLength - patterLength + 1)
{
for (size_t j = 0; j < kPrimeMods.size(); ++j)
{
textHashes[j] -= (text[i - 1]) * maxPower[j];
textHashes[j] += kPrimeMods[j]; // Ensure non-negative
textHashes[j] %= kPrimeMods[j];
textHashes[j] *= P;
textHashes[j] += kPrimeMods[j];
textHashes[j] %= kPrimeMods[j];
textHashes[j] += (text[i + patterLength - 1]);
textHashes[j] += kPrimeMods[j];
textHashes[j] %= kPrimeMods[j];
}
}
} while (i < textLength - patterLength + 1);
}
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> patterHashes(kPrimeMods.size());
for (size_t i = 0; i < kPrimeMods.size(); ++i)
{
patterHashes[i] = computePatternHash(x, kPrimeMods[i]);
}
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] << ' ';
}
}