Pagini recente » Cod sursa (job #1520730) | Cod sursa (job #3207776) | Cod sursa (job #1296412) | Cod sursa (job #3037941) | Cod sursa (job #2207645)
#include <stdio.h>
#include <string.h>
#define M1 666013
#define M2 1000003
char mare[2000001], mic[2000001];
int rezultate[1000], cate;
inline long long lookup(char c) {
if(c <= '9') return c - '0';
if(c <= 'Z') return c - 'A' + 10;
return c - 'a' + 36;
}
int main() {
FILE *fin = fopen("strmatch.in", "r");
fgets(mic, 2000001, fin);
fgets(mare, 2000001, fin);
mic[strcspn(mic, "\r\n")] = 0;
mare[strcspn(mare, "\r\n")] = 0;
int l_mic = strlen(mic);
int l_mare = strlen(mare);
fclose(fin);
long long hash1 = 0, hash2 = 0, // hashurile bucatii mici
puterea1 = 1, puterea2 = 1, // 62 la puterea l_mic-1
rolling1 = 0, rolling2 = 0; // hashurile secventelor din aia mare
for(int i=0; i<l_mic; i++) {
hash1 = (hash1 * 62 + lookup(mic[i])) % M1;
hash2 = (hash2 * 62 + lookup(mic[i])) % M2;
rolling1 = (rolling1 * 62 + lookup(mare[i])) % M1;
rolling2 = (rolling2 * 62 + lookup(mare[i])) % M2;
if(i != 0) { // sa sarim _un singur_ pas
puterea1 = puterea1 * 62 % M1;
puterea2 = puterea2 * 62 % M2;
}
}
for(int i=l_mic; i<l_mare; i++) {
if(hash1 == rolling1 && hash2 == rolling2) {
if(cate < 1000) rezultate[cate] = i-l_mic;
cate++;
}
const int ce_scot_1 = lookup(mare[i-l_mic]) * puterea1 % M1,
ce_scot_2 = lookup(mare[i-l_mic]) * puterea2 % M2;
rolling1 = ((rolling1 - ce_scot_1 + M1) % M1 // scoate primul
* 62 + lookup(mare[i])) % M1; // baga urmatorul
rolling2 = ((rolling2 - ce_scot_2 + M2) % M2 * 62 + lookup(mare[i])) % M2;
}
FILE *fout = fopen("strmatch.out", "w");
fprintf(fout, "%d\n", cate);
for(int i=0; i<cate; i++)
fprintf(fout, "%d ", rezultate[i]);
fprintf(fout, "\n");
fclose(fout);
return 0;
}