Pagini recente » Cod sursa (job #660838) | Cod sursa (job #301571) | Cod sursa (job #2067615) | Cod sursa (job #2671716) | Cod sursa (job #332758)
Cod sursa(job #332758)
//Rabin-Karp
#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
#define N 2000001 //lungimea maxima a unui sir
#define mod1 2000003
#define mod2 666013
using namespace std;
char a[N], p[N]; //sirul p este cautat in a
int n, m; // n = |p|; m = |a|
vector<int> sol;// primele 1000 de aparitii
void rk()
{
int NR = 0; //nr de aparitii a lui p in a
int pw1_255=1, i, pw2_255=1; // pw1_255 = 255^(n-1) % mod1 iar pw2_255 = 255^(n-1) % mod2
int hp1=0, h1=0; //hp1 = hashul 1 al sirului p, h1 = hashul 1 al unei subsecvente din a
int hp2=0, h2=0; //la fel pt hashul 2
for(i = 1; i < n; ++i)
//calculam 255^(n-1) % mod 1/2
pw1_255 *=255, pw1_255 %= mod1,
pw2_255 *= 255, pw2_255 %= mod2;
for(i = 1; i <= n; ++i)
//calculam hashurile lui p
hp1 = hp1 * 255 + p[i], hp1 %= mod1,
hp2 = hp2 * 255 + p[i], hp2 %= mod2;
for(i = 1; i < n; ++i)
//calculam hashurile subsecventei a[1..n-1]
h1 = h1 * 255 + a[i], h1 %= mod1,
h2 = h2 * 255 + a[i], h2 %= mod2;
for(i = n; i <= m; ++i)
{
//adaugam caracterul a[i] la hashuri
h1 = h1 * 255 + a[i], h1 %= mod1;
h2 = h2 * 255 + a[i], h2 %= mod2;
//daca cele 4 hashuri coincid (2 cate 2) => am gasit un pattern
if(h1 == hp1)
if(h2 == hp2) if(sol.size() < 1000) sol.push_back(i-n), ++NR;
else ++NR;
//scadem caracterul a[i-n+1] din hashuri
h1 -= (a[i-n+1] * pw1_255)% mod1;
h2 -= (a[i-n+1] * pw2_255) % mod2;
while(h1 < 0) h1 += mod1;
while(h2 < 0) h2 += mod2;
}
printf("%d\n", NR);
for(int i = 0; i < min(1000, (int)sol.size()); ++i) printf("%d ", sol[i]);
printf("\n");
}
int main()
{
freopen("strmatch.in","r",stdin);
freopen("strmatch.out","w",stdout);
gets(p);
gets(a);
n = strlen(p);
m = strlen(a);
int i;
//mentinem a[1...m] si p[1...n]
for(i = n; i > 0; --i) p[i] = p[i-1];
for(i = m ; i > 0;--i) a[i] = a[i-1];
rk();
return 0;
}