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;
}