Cod sursa(job #2793700)

Utilizator Victor2006Nicola Victor-Teodor Victor2006 Data 3 noiembrie 2021 21:42:29
Problema Potrivirea sirurilor Scor 80
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.54 kb
#include <stdio.h>
#include <string.h>
#include <vector>
#define BASE 127
#define MAX_HASH 666013
#define MAX_LEN 2000000
#define BASE1 ('z' + 1)
#define MAX_HASH1 1000007
#define N 1000

char word[MAX_LEN + 1];
int nw;

char pattern[MAX_LEN + 1];
int np;

int ans[N];
int n;

int computeHash( char str[], int n, int b, int mod ) {
    int hashVal;

    hashVal = 0;
    for ( int i = 0; i < n; i ++ )
        hashVal = (hashVal * b + str[i]) % mod;

    return hashVal;
}

int addToHash( int valHash, char ch, int b, int mod ) {
    valHash = (valHash * b + ch) % mod;
    return valHash;
}

int removeFromHash( int valHash, char ch, int put, int mod ) {
    valHash -= (ch * put) % mod;
    if ( valHash < 0 )
        valHash += mod;
    return valHash;
}

int isEqual( char v1[], char v2[], int n ) {
    int i = 0;
    while ( i < n && v1[i] == v2[i] )
        i ++;
    return (i == n);
}

int main() {
    FILE *fin, *fout;
    int hashVal, hashP, put, hashVal1, hashP1, put1, ch;

    fin = fopen( "strmatch.in", "r" );
    np = 0;
    ch = fgetc( fin );
    while ( ch != '\n' ) {
        pattern[np ++] = ch;
        ch = fgetc( fin );
    }
    pattern[np] = 0;

    nw = 0;
    ch = fgetc( fin );
    while ( ch != '\n' ) {
        word[nw ++] = ch;
        ch = fgetc( fin );
    }
    word[nw] = 0;
    fclose( fin );

    hashVal = hashP = hashVal1 = hashP1 = 0;
    put = put1 = 1;
    for ( int i = 0; i < np - 1; i ++ ) {
        //printf( "%d %d\n", codif[pattern[i]], codif[word[i]] );
        hashVal = addToHash( hashVal, word[i], BASE, MAX_HASH );
        hashP = addToHash( hashP, pattern[i], BASE, MAX_HASH );
        put *= BASE;
        put %= MAX_HASH;

        hashVal1 = addToHash( hashVal1, word[i], BASE1, MAX_HASH1 );
        hashP1 = addToHash( hashP1, pattern[i], BASE1, MAX_HASH1 );
        put1 *= BASE1;
        put1 %= MAX_HASH1;
    }
    hashP = addToHash( hashP, pattern[np - 1], BASE, MAX_HASH );
    //hashVal = addToHash( hashVal, word[np - 1], BASE, MAX_HASH );
    hashP1 = addToHash( hashP1, pattern[np - 1], BASE1, MAX_HASH1 );
    //hashVal1 = addToHash( hashVal1, word[np - 1], BASE1, MAX_HASH1 );

    /*printf( "%d %d\n", computeHash( pattern, np, BASE, MAX_HASH ), hashP );
    printf( "%d %d\n", computeHash( pattern, np, BASE1, MAX_HASH1 ), hashP1 );
    printf( "\n\n" );

    printf( "!!!%d %d\n\n", np, nw );*/

    n = 0;
    for ( int i = np; i <= nw; i ++ ) {
        hashVal = addToHash( hashVal, word[i - 1], BASE, MAX_HASH );
        hashVal1 = addToHash( hashVal1, word[i - 1], BASE1, MAX_HASH1 );

        /*printf( "%d %d\n", computeHash( word + i - np, np, BASE, MAX_HASH ), hashVal );
        printf( "%d %d\n", computeHash( word + i - np, np, BASE1, MAX_HASH1 ), hashVal1 );
        printf( "\n\n" );*/

        if ( hashP == hashVal && hashP1 == hashVal1 && isEqual( pattern, word + i - np, np ) ) {
            if ( n < N )
                ans[n] = i - np;
            n ++;
        }
        hashVal = removeFromHash( hashVal, word[i - np], put, MAX_HASH );
        hashVal1 = removeFromHash( hashVal1, word[i - np], put1, MAX_HASH1 );
    }

    fout = fopen( "strmatch.out", "w" );
    fprintf( fout, "%d\n", n );
    n = std::min( n, N );
    for ( int i = 0; i < n; i ++ )
        fprintf( fout, "%d ", ans[i] );
    if ( n > 0 )
        fprintf( fout, "\n" );
    /*for ( int i = 0; i < MAX_LEN; i ++ )
        fprintf( fout, "A" );*/
    //fprintf( fout, "%d %d\n", hashVal, hashP );
    fclose( fout );
    return 0;
}