Pagini recente » Cod sursa (job #2493002) | Cod sursa (job #215420) | Cod sursa (job #1604847) | Cod sursa (job #1910317) | Cod sursa (job #3300618)
#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
using namespace std;
ifstream fin("strmatch.in");
ofstream fout("strmatch.out");
#define int long long
char A[2000006];
char B[2000006];
int mod1 = 1000000007;
int mod2 = 1000000009;
vector<int> v;
int32_t main()
{
v.reserve(1000);
fin.getline(A, 2000006);
fin.getline(B, 2000006);
int na = strlen(A);
int nb = strlen(B);
/// daca lenA > lenB => nu merge
if (na > nb) {
fout << 0 << '\n';
return 0;
}
/// îl hash-uiesc pe A cu mod1 și mod2
int64_t ha1 = 0, p1 = 1;
int64_t ha2 = 0, p2 = 1;
for (int i = 0; i < na; i++) {
ha1 = (ha1 * 73 + A[i]) % mod1;
ha2 = (ha2 * 73 + A[i]) % mod2;
/// rețin puterea maximă folosită pentru fiecare hash
if (i != 0) {
p1 = (p1 * 73) % mod1;
p2 = (p2 * 73) % mod2;
}
}
/// îl hash-uiesc pe B treptat cu mod1 și mod2
/// fac pentru primele na char din B ca să am "baza" de la care plec
int hb1 = 0;
int hb2 = 0;
for (int i = 0; i < na; i++) {
hb1 = (hb1 * 73 + B[i]) % mod1;
hb2 = (hb2 * 73 + B[i]) % mod2;
}
/// dacă se potrivesc ambele hash-uri la început
if (ha1 == hb1 && ha2 == hb2) {
v.push_back(0);
}
/// trec prin restul din B
for (int i = na; i < nb; i++) {
/// tai valoarea primului char și adaug încă unul la final
int val_ch_ex = (int64_t)(B[i - na] * p1) % mod1; // ce tai
int val_hash_atm = (hb1 - val_ch_ex + mod1) % mod1;
hb1 = ((int64_t)val_hash_atm * 73 + B[i]) % mod1; // adaug noul char
val_ch_ex = (int64_t)(B[i - na] * p2) % mod2; // ce tai
val_hash_atm = (hb2 - val_ch_ex + mod2) % mod2; // hash-ul cu primul char tăiat
hb2 = ((int64_t)val_hash_atm * 73 + B[i]) % mod2; // adaug noul char
/// verific dacă se potrivesc
if (ha1 == hb1 && ha2 == hb2) { // <— eliminată limita v.size()<1000
v.push_back(i - na + 1); // poziția de început (0-based)
}
}
fout << v.size() << '\n';
for (int i = 0; i < (int)v.size(); i++) {
fout << v[i] << " ";
}
return 0;
}