Cod sursa(job #2793161)

Utilizator Victor2006Nicola Victor-Teodor Victor2006 Data 3 noiembrie 2021 09:55:50
Problema Potrivirea sirurilor Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.29 kb
#include <stdio.h>
#include <string.h>
#include <vector>
#define BASE 62
#define MAX_HASH (1 << 16)
#define MAX_LEN 2000000

char codif['z' + 1];

char word[MAX_LEN + 1];
int nw;

char pattern[MAX_LEN + 1];
int np;

int ans[MAX_LEN];
int n;

int addToHash( int valHash, char ch ) {
    valHash = ( valHash * BASE + codif[ch] ) % MAX_HASH;
    return valHash;
}

int removeFromHash( int valHash, char ch, int put ) {
    valHash -= (codif[ch] * put) % MAX_HASH;
    if ( valHash < 0 )
        valHash += MAX_HASH;
    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;

    int cnt = 0;
    for ( int i = '0'; i <= '9'; i ++ )
        codif[i] = cnt ++;
    for ( int i = 'A'; i <= 'Z'; i ++ )
        codif[i] = cnt ++;
    for ( int i = 'a'; i <= 'z'; i ++ )
        codif[i] = cnt ++;

    //for ( int i = 'A'; i <= 'Z'; i ++ )
        //printf( "%d ", codif[i] );

    fin = fopen( "strmatch.in", "r" );
    fgets( pattern, MAX_LEN, fin );
    np = strlen( pattern );
    pattern[np --] = 0; // scap de '\n'

    fgets( word, MAX_LEN, fin );
    nw = strlen( word );
    word[nw --] = 0; // scap de '\n'
    fclose( fin );

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

    n = 0;
    for ( int i = np; i <= nw; i ++ ) {
        hashVal = addToHash( hashVal, word[i - 1] );
        if ( hashP == hashVal && isEqual( pattern, word + i - np, np ) )
            ans[n ++] = i - np;
        hashVal = removeFromHash( hashVal, word[i - np], put );
    }

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