Pagini recente » Cod sursa (job #1813648) | Cod sursa (job #787853) | Cod sursa (job #2882542) | Cod sursa (job #2665952) | Cod sursa (job #2067903)
#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
#include <climits>
using namespace std;
ifstream in("strmatch.in");
ofstream out("strmatch.out");
typedef unsigned long long ull; //asta e numai pentru hash-uri cand vrei sa aproximezi solutia, cand nu gasesti rezolvare analitica
int const nmax = 2000000;
ull const base = 47;
string s1, s2;
ull hash2[nmax];
int main() {
/*
ull i = 0;
ull j = i - 1u; //cel mai mare numar care poate fi reprezentat
cout << i << " " << j << " " << (((ull)LONG_LONG_MAX) * 2 + 1) << endl;
ull k = j * j; //(2^64 - 1) ^ 2 = 2^128 - 2^65 + 1 = 1 - 2^65 = 0 - (2^65 - 1) = 111..1111 - (1111..11111 - 1) = 1
//te poti baza pe unsinged long long ca fiind un modulo 2^64. Numai ca e mai rapid decat modulo
//conform standardului C++, ar trebui sa fie reliable
cout<< k;
*/
//putem implementa foarte comod hash-uri pe unsinged long long
in >> s1 >> s2;
int n1 = s1.size();
ull needle = 0;
ull basep = 1;
for(int i = 0 ; i < n1; i++) {
needle = needle * base + (s1[i] - 'A');
basep = basep * base;
}
hash2[0] = (s2[0] - 'A');
for(int i=1; i<s2.size(); i++) {
hash2[i] = hash2[i-1] * base + (s2[i] - 'A');
}
int nsol = 0;
vector<int> sol;
ull h = hash2[n1 - 1]; //de la 0 pana la n1 - 1
if(h == needle) {
nsol++;
if(nsol <= 1000)
sol.push_back(0);
}
for(int i = n1; i < s2.size(); i++) {
//de la i - n1 + 1 pana la i
h = hash2[i] - hash2[i - n1] * basep; // s[0] * b ^ i - s[0] z
if(h == needle) {
nsol++;
if(nsol <= 1000)
sol.push_back(i - n1 + 1);
}
}
out<< nsol << '\n';
for(int i = 0; i < sol.size(); i++) {
out << sol[i] << " ";
}
//hash2[0] = s[0]
//hash2[1] = s[0] * b + s[1]
//hash2[2] = s[0] * b^2 + s[1] * b + s[2]
return 0;
}