Cod sursa(job #2792801)

Utilizator iraresmihaiiordache rares mihai iraresmihai Data 2 noiembrie 2021 12:23:28
Problema Potrivirea sirurilor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.29 kb
#include <stdio.h>
#include <string.h>
#define MAX_LENGHT 2000000
#define HASH_SIZE_1 65536
#define HASH_SIZE_2 65537
#define FACTOR1 15
#define FACTOR2 34

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 hash_s) {
    int result, i;

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

    return result;
}

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

    result = 1;
    while ( p ) {
        if ( p % 2 == 1 ) {
            result = ((long long) result * n) % hash_s;
        }
        n = ((long long) n * n) % hash_s;
        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, int hash_s) {
    result = result - ((long long) nr * p) % hash_s;
    if ( result < 0 )
        result += hash_s;

    return result;
}

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

void getResult(int poz) {

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

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

bool alphabeth(char ch) {
    return (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
}

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);
    while ( !alphabeth(s[s_lenght]) ) {
        s_lenght--;
    }
    s_lenght++;
    word_lenght = strlen(word);
    while ( !alphabeth(word[word_lenght]) ) {
        word_lenght--;
    }
    word_lenght++;

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

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

    while ( i < s_lenght ) {
        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;
}