Cod sursa(job #2792700)

Utilizator iraresmihaiiordache rares mihai iraresmihai Data 2 noiembrie 2021 10:46:42
Problema Potrivirea sirurilor Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.83 kb
#include <stdio.h>
#include <string.h>
#define MAX_LENGHT 2000000
#define HASH_SIZE 65536
#define FACTOR1 15
#define FACTOR2 17

using namespace std;

char word[MAX_LENGHT + 1];
char s[MAX_LENGHT + 1];

int pozApperances[1000];
int nrApperances, s_lenght, word_lenght;

int pwr_max_hash1, pwr_max_hash2, res_word_hash1, res_word_hash2, res_seq_hash1, res_seq_hash2;

int calcHash(char seq[], int lenght, int factor) {
    int result, i;

    result = 0;
    for ( i = 0; i < lenght; i++ ) {
        result = ((long long) result * factor + seq[i]) % HASH_SIZE;
    }

    return result;
}

int pwr(int n, int p) {
    int result;

    result = 1;
    while ( p ) {
        if ( p % 2 == 1 ) {
            result = ((long long) result * n) % HASH_SIZE;
        }
        n = ((long long) n * n) % HASH_SIZE;
        p /= 2;
    }

    return result;
}

bool compareResults() {
    return res_word_hash1 == res_seq_hash1 && res_word_hash2 == res_seq_hash2;
}

int eraseNr(int nr, int p, int result) {
    result = result - ((long long) nr * p) % HASH_SIZE;
    if ( result < 0 )
        result += HASH_SIZE;

    return result;
}

int addNr(int nr, int p, int result) {
    result = ((long long) result * p + nr) % HASH_SIZE;
    return result;
}

void getResult(int poz) {

    res_seq_hash1 = eraseNr(s[poz - word_lenght], pwr_max_hash1, res_seq_hash1);
    res_seq_hash2 = eraseNr(s[poz - word_lenght], pwr_max_hash2, res_seq_hash2);
    res_seq_hash1 = addNr(s[poz], FACTOR1, res_seq_hash1);
    res_seq_hash2 = addNr(s[poz], FACTOR2, res_seq_hash2);

    if ( compareResults() ) {
        pozApperances[nrApperances] = poz - word_lenght + 1;
        nrApperances++;
    }
}

int main() {
    FILE *fin, *fout;
    fin = fopen("strmatch.in", "r");
    fout = fopen("strmatch.out", "w");

    int i;

    fgets(word, MAX_LENGHT + 1, fin);
    fgets(s, MAX_LENGHT + 1, fin);
    s_lenght = strlen(s);
    s_lenght--;
    word_lenght = strlen(word);
    word_lenght--;

    nrApperances = 0;
    pwr_max_hash1 = pwr(FACTOR1, word_lenght - 1);
    pwr_max_hash2 = pwr(FACTOR2, word_lenght - 1);
    res_word_hash1 = calcHash(word, word_lenght, FACTOR1);
    res_word_hash2 = calcHash(word, word_lenght, FACTOR2);
    res_seq_hash1 = calcHash(s, word_lenght, FACTOR1);
    res_seq_hash2 = calcHash(s, word_lenght, FACTOR2);

    i = word_lenght;
    if ( compareResults() ) {
        pozApperances[nrApperances] = i - word_lenght;
        nrApperances++;
    }

    while ( i < s_lenght && nrApperances < 1000 ) {
        getResult(i);
        i++;
    }

    fprintf(fout, "%d\n", nrApperances);
    for ( i = 0; i < nrApperances && i < 1000; i++ ) {
        fprintf(fout, "%d ", pozApperances[i]);
    }
    fprintf(fout, "\n");

    fclose(fin);
    fclose(fout);
    return 0;
}