Laborator 7

Problema

Se da un fisier binar continand 100.000 numere intregi. Acest fisier poate fi descarcat aici. Sunt prezente toate numerele intregi intre 0 si 99.999, intr-o ordine aleatoare. Se cere:

  • Sa se afiseze intr-un fisier text continutul fisierului binar de intrare. Fiecare din cei 100.000 de intregi va fi delimitat de vecinii sai printr-un caracter '|'

  • Sa se foloseasca algoritmul de sortare prin interclasare cu 3 benzi pentru a sorta descrescator fisierul de intrare

  • Sa se contorizeze cate operatii de citire din fisier si scriere in fisier executa algoritmul, precum si numarul de comparatii executate

  • Sa se afiseze intr-un alt fisier text continutul fisierului sortat, intr-un format similar celui de mai sus

Rezolvare

#include <stdio.h>

#include <stdlib.h>

int nr_scrieri=0;

int nr_citiri=0;

int nr_comp=0;

void move( FILE* source , FILE* destination , int size )

{

int i;

int x; // aici trebuie folosit un element de tipul elementelor din fisier

i = 0;

while ( i < size && !feof( source ) )

{

if ( fread( &x , sizeof(int) , 1 , source ) < 1 )

break;

fwrite( &x , sizeof( int ) , 1 , destination );

i++;

}

nr_citiri++;

nr_scrieri++;

}

void distribute( char* file_name , char* auxiliary1 , char* auxiliary2 , int size )

{

FILE* source;

FILE* destination1;

FILE* destination2;

source = fopen( file_name , "rb" );

if ( !source )

{

printf( "ERROR! File not available\n" );

return;

}

destination1 = fopen( auxiliary1 , "wb" );

destination2 = fopen( auxiliary2 , "wb" );

while ( !feof( source ) )

{

move( source , destination1 , size );

move( source , destination2 , size );

}

fclose(source);

fclose(destination1);

fclose(destination2);

}

void merge( char* file_name , char* auxiliary1 , char* auxiliary2 , int size , int* repeat )

{

int i , j;

int x; // aici trebuie folosit un element de tipul elementelor din fisier

int y; // aici trebuie folosit un element de tipul elementelor din fisier

int eof1 , eof2;

FILE* source1;

FILE* source2;

FILE* destination;

source1 = fopen( auxiliary1 , "rb" );

if ( !source1 )

{

printf( "ERROR! File not available\n" );

return;

}

source2 = fopen( auxiliary2 , "rb" );

if ( !source2 )

{

printf( "ERROR! File not available\n" );

return;

}

destination = fopen( file_name , "wb" );

eof1 = feof( source1 );

eof2 = feof( source2 );

if ( !eof1 )

if ( fread( &x , sizeof( int ) , 1 , source1 ) < 1 )

eof1 = 1;

if ( !eof2 )

if ( fread( &y , sizeof( int ) , 1 , source2 ) < 1 )

eof2 = 1;

do

{

i = 0;

j = 0;

while ( i < size && j < size && !eof1 && !eof2 )

{

if ( x > y )

{

fwrite( &x , sizeof( int ) , 1 , destination );

nr_scrieri++;

i++;

if ( feof( source1 ) )

eof1 = 1;

else if ( fread( &x , sizeof( int ) , 1 , source1 ) < 1 )

eof1 = 1;

nr_comp++;

}

else

{

fwrite( &y , sizeof( int ) , 1 , destination );

nr_scrieri++;

j++;

if ( feof( source2 ) )

eof2 = 1;

else if ( fread( &y , sizeof( int ) , 1 , source2 ) < 1 )

eof2 = 1;

nr_comp++;

}

}

while ( i < size && !eof1 )

{

fwrite( &x , sizeof( int ) , 1 , destination );

nr_scrieri++;

i++;

if ( feof( source1 ) )

eof1 = 1;

else if ( fread( &x , sizeof( int ) , 1 , source1 ) < 1 )

eof1 = 1;

}

while ( j < size && !eof2 )

{

fwrite( &y , sizeof( int ) , 1 , destination );

nr_scrieri++;

j++;

if ( feof( source2 ) )

eof2 = 1;

else if ( fread( &y , sizeof( int ) , 1 , source2 ) < 1 )

eof2 = 1;

}

if ( !eof1 || !eof2 )

*repeat = 1;

} while ( !eof1 || !eof2 );

fclose(source1);

fclose(source2);

fclose(destination);

}

void three_way_sequence_merging( char* file_name , char* auxiliary1 , char* auxiliary2 )

{

int size;

int repeat;

size = 1;

do

{

distribute( file_name , auxiliary1 , auxiliary2 , size );

repeat = 0;

merge( file_name , auxiliary1 , auxiliary2 , size , &repeat );

size = size * 2;

} while ( repeat != 0 );

}

int main()

{

printf("Hello world!\n");

FILE *f;

f=fopen("data2.bin","rb");

if(f==NULL)

{

printf("Eroare la deschiderea fisierului sursa");

exit(1);

}

FILE *g;

g=fopen("out.txt","w");

if(g==NULL)

{

printf("Eroare la deschiderea fisierului destinatie");

exit(1);

}

move(f,g,100000);

FILE *aux1;

FILE *aux2;

FILE *h;

FILE *t;

aux1=fopen("aux1.bin","wb");

aux2=fopen("aux2.bin","wb");

h=fopen("chestii.txt","w");

t=fopen("chestii2.txt","w");

three_way_sequence_merging("data2.bin","aux1.bin","aux2.bin");

move(aux1,h,100000);

move(aux2,t,100000);

printf("Numar citiri:%d\nNumar scrieri:%d\nNumar comparatii:%d",nr_citiri,nr_scrieri,nr_comp);

return 0;

}