Cod sursa(job #2792046)

Utilizator LuciBBadea Lucian LuciB Data 31 octombrie 2021 18:59:48
Problema Potrivirea sirurilor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.94 kb
#include <stdio.h>
#include <string.h>
#define LENMAX 2000000

#define BASE 256
#define HASH1 100007
#define HASH2 100021

char a[LENMAX + 1], b[LENMAX + 1];
int aLen, bLen;

struct hash{
    int h1, h2;
};
int ans[1000], matches;

void eraseNewLine(char str[], int& length) {
  if (str[length - 1] == '\n')
    str[--length] = 0;
}

int main() {
    int i, p1, p2;
    hash hashA, hashB;
    FILE *fin, *fout;

    fin = fopen("strmatch.in", "r");
    fgets(a, sizeof(a), fin);
    aLen = strlen(a);
    eraseNewLine(a, aLen);
    fgets(b, sizeof(b), fin);
    bLen = strlen(b);
    eraseNewLine(b, bLen);
    fclose(fin);

    p1 = p2 = 1;
    for(i = 0; i < aLen - 1; i++) {
        p1 = (p1 * BASE) % HASH1;
        p2 = (p2 * BASE) % HASH2;
    }
    hashA.h1 = hashA.h2 = 0;
    hashB.h1 = hashB.h2 = 0;
    for(i = 0; i < aLen; i++) {
        hashA.h1 = (hashA.h1 * BASE + a[i]) % HASH1;
        hashA.h2 = (hashA.h2 * BASE + a[i]) % HASH2;
        hashB.h1 = (hashB.h1 * BASE + b[i]) % HASH1;
        hashB.h2 = (hashB.h2 * BASE + b[i]) % HASH2;
    }
    matches = 0;
    i = aLen;
    while(i <= bLen) {
        if(hashA.h1 == hashB.h1 && hashA.h2 == hashB.h2) {
            if(matches < 1000)
                ans[matches] = i - aLen;
            matches++;
        }
        //printf("%d %d %d %d\n", hashA.h1, hashA.h2, hashB.h1, hashB.h2);
        hashB.h1 -= b[i - aLen] * p1 % HASH1;
        hashB.h2 -= b[i - aLen] * p2 % HASH2;
        if(hashB.h1 < 0)
            hashB.h1 += HASH1;
        if(hashB.h2 < 0)
            hashB.h2 += HASH2;
        hashB.h1 = (hashB.h1 * BASE + b[i]) % HASH1;
        hashB.h2 = (hashB.h2 * BASE + b[i]) % HASH2;
        i++;
    }

    fout = fopen("strmatch.out", "w");
    fprintf(fout, "%d\n", matches);
    if(matches > 1000)
        matches = 1000;
    for(i = 0; i < matches; i++)
        fprintf(fout, "%d ", ans[i]);
    fclose(fout);

    return 0;
}