#include #include #include #include long filesize(FILE *stream) { long curpos, length; curpos = ftell(stream); fseek(stream, 0L, SEEK_END); length = ftell(stream); fseek(stream, curpos, SEEK_SET); return length; } int fEOF(FILE *stream) { return (ftell(stream) == filesize(stream) || feof(stream)); } /* function IntToStr(I: Longint): String; { Convert any integer type to a string } var S: string[11]; begin Str(I, S); IntToStr := S; end; */ void MakeFile() { FILE *f; // var // F: file of integer; // i,n,k: integer; // begin if((f = fopen("vyvod.txt", "rb")) != NULL) { fclose(f); unlink("vyvod.txt"); } // assign(f, 'vyvod.txt'); // {$i-} reset(f); {$i+} // if ioresult = 0 then begin // close(f); // erase(f); // end; randomize(); f = fopen("L3.txt", "wb"); // AssignFile(F,'L3.txt'); // Rewrite(F); int n = 5; for(int i = 1; i <= n; i++) { int k = n-i; printf("(memo2): %d\n", k); fwrite(&k, sizeof(k), 1, f); // write(F,k); } fclose(f); // CloseFile(F); } //вывод получившегося файла void ShowFile() { //var // F: File of integer; // b: integer; //begin FILE *f; f = fopen("vyvod.txt", "rb"); // AssignFile(F,'vyvod.txt'); // Reset(F); while(!feof(f)) { int b; if( fread(&b, sizeof(b), 1, f) ) { // read(F,b); // writeln('memo1: ', b); printf("(memo1): %d\n", b); } } // CloseFile(F); fclose(f); } void ShowFile(const char *s) { //var // F: File of integer; // b: integer; //begin FILE *f; f = fopen(s, "rb"); // AssignFile(F,'vyvod.txt'); // Reset(F); while(!feof(f)) { int b; if( fread(&b, sizeof(b), 1, f) ) { // read(F,b); // writeln('memo1: ', b); printf("(test file %s): %d\n", s, b); } } // CloseFile(F); fclose(f); } //собственно сортировка void MergeSort() { const int T = 3; const int p = 2; //var // A,D,Dost,TAPE,sort: array[1..T] of integer; int A[T+1],D[T+1],Dost[T+1],TAPE[T+1],sort[T+1]; // array[0 .. T-1] of integer; // i,j,l,a1,zap,sumA,sumD,min,mini,zerro,Dmax: integer; int i,j,l,a1,zap,sumA,sumD,min,mini,zerro,Dmax; // Lenta: array[1..3] of File of integer; FILE *Lenta[4]; char s[20]; // s:string; Dmax = 1; //заполняем первую последовательность MakeFile(); //задаем начальные установки for(j = 1; j <= T-1; j++) { A[j]=1; D[j]=1; TAPE[j]=j; } A[T]=0; D[T]=0; TAPE[T]=T; /* A = {1, 1, 0} D = {1, 1, 0} Tape = {1, 2, 3} */ l=1; j=1; //связываем "ленты" с реальными файлами Lenta[1] = fopen("L1.txt", "wb"); printf("rewrite Lenta[1]\n"); Lenta[2] = fopen("L2.txt", "wb"); printf("rewrite Lenta[2]\n"); Lenta[3] = fopen("L3.txt", "rb"); printf("reset Lenta[3]\n"); //AssignFile(Lenta[1],'L1.txt'); //AssignFile(Lenta[2],'L2.txt'); //AssignFile(Lenta[3],'L3.txt'); //Rewrite(Lenta[1]); //Rewrite(Lenta[2]); //Reset(Lenta[3]); //распределяем имеющиеся записи //на каждой ленте будет одно из последовательных чисел Фибоначчи //порядка Т-1 while(!fEOF(Lenta[3])) { fread(&zap, sizeof(zap), 1, Lenta[3]); printf("read L3: %d\n", zap); fwrite(&zap, sizeof(zap), 1, Lenta[j]); printf("write L%d: %d\n", j, zap); D[j]=D[j]-1; if(!fEOF(Lenta[3])) { if(D[j] < D[j+1]) j += 1; else if(D[j] == 0) { l = l+1; a1 = A[1]; for(j = 1; j <= p; j++) { D[j]=a1+A[j+1]-A[j]; A[j]=a1+A[j+1]; } j = 1; } else j = 1; } } //готовим данные для сортировки sumD=0; sumA=0; for(j = 1; j <= T-1; j++) { sumD=sumD+D[j]; sumA=sumA+A[j]; for(i = 1; i <= D[j]; i++) { zap = MAXINT; fwrite(&zap, sizeof(zap), 1, Lenta[j]); printf("write L%d: %d\n", j, zap); } D[j] = 1; } for(j = 1; j <= T-1; j++) { fflush(Lenta[TAPE[j]]); fclose(Lenta[TAPE[j]]); sprintf(s, "L%d.txt\0", TAPE[j]); Lenta[TAPE[j]] = fopen(s, "rb"); // rewind(Lenta[TAPE[j]]); // fseek(Lenta[TAPE[j]], 0, SEEK_SET); printf("rewind L%d\n", TAPE[j]); } // ShowFile("L1.txt"); fflush(Lenta[TAPE[T]]); fclose(Lenta[TAPE[T]]); // char s[20]; sprintf(s, "L%d.txt\0", TAPE[T]); Lenta[TAPE[T]] = fopen(s, "wb"); printf("rewrite L%d\n", TAPE[T]); Dmax=0; //пока все не отсортировано while(Dmax < sumA) { //пока ни на одной ленте не кончились серии // while( (!fEOF(Lenta[TAPE[1]])) && (!fEOF(Lenta[TAPE[2]])) ) { do { printf("checking EOF: %d and %d\n", TAPE[1], TAPE[2]); for(j = 1; j <= T; j++) Dost[j] = D[j]; zerro=0; //заполнение текущими эл-тами for(i=1; i <= T-1; i++) { fread(&sort[TAPE[i]], sizeof(sort[0]), 1, Lenta[TAPE[i]]); printf("read L%d: %d\n", TAPE[i], sort[TAPE[i]]); } //для каждой серии while(zerro < T-1) { min = MAXINT; for(i = 1; i <= T-1; i++) if((sort[TAPE[i]] <= min) && (Dost[TAPE[i]] > 0)) { min = sort[TAPE[i]]; mini = i; } fwrite(&min, sizeof(min), 1, Lenta[TAPE[T]]); Dost[TAPE[mini]] = Dost[TAPE[mini]] - 1; if(Dost[TAPE[mini]] > 0) { fread(&sort[TAPE[mini]], sizeof(sort[0]), 1, Lenta[TAPE[mini]]); printf("read L%d: %d\n", TAPE[mini], sort[TAPE[mini]]); } else { sort[TAPE[mini]] = MAXINT; zerro=zerro+1; } } // printf("file: L%d :: size = %ld, curr = %ld\n", TAPE[1], filesize(Lenta[TAPE[1]]), ftell(Lenta[TAPE[1]])); // printf("file: L%d :: size = %ld, curr = %ld\n", TAPE[2], filesize(Lenta[TAPE[2]]), ftell(Lenta[TAPE[2]])); } while( (!fEOF(Lenta[TAPE[1]])) && (!fEOF(Lenta[TAPE[2]])) ); //меняем ленты местами for(i=1; i <= T-1; i++) if(fEOF(Lenta[TAPE[i]])) { D[TAPE[T]]=0; for(j=1; j<=T-1;j++) D[TAPE[T]]=D[TAPE[T]]+D[TAPE[j]]; Dmax = D[TAPE[T]]; // fclose(Lenta[Tape[T]]); fflush(Lenta[TAPE[T]]); sprintf(s, "L%d.txt\0", TAPE[T]); Lenta[TAPE[j]] = fopen(s, "rb"); // rewind(Lenta[TAPE[T]]); j=TAPE[i]; TAPE[i]=TAPE[T]; TAPE[T]=j; fflush(Lenta[TAPE[T]]); fclose(Lenta[TAPE[T]]); // char s[20]; sprintf(s, "L%d.txt\0", TAPE[T]); Lenta[TAPE[T]] = fopen(s, "wb"); /* CloseFile(Lenta[Tape[T]]); Rewrite(Lenta[Tape[T]]); */ } } //"обрезаем" фиктивные элементы //переименовываем отсортированный файл //закрываем и удаляем все остальные файлы for(i=1; i <= T; i++) { if(filesize(Lenta[TAPE[i]]) != 0) { fseek(Lenta[TAPE[i]],(long)(sumA-sumD), SEEK_SET); chsize(fileno(Lenta[TAPE[i]]), ftell(Lenta[TAPE[i]])); //truncate(Lenta[Tape[i]]); fclose(Lenta[TAPE[i]]); sprintf(s, "L%d.txt\0", TAPE[i]); rename(s, "vyvod.txt"); } else { sprintf(s, "L%d.txt\0", TAPE[i]); fclose(Lenta[TAPE[i]]); unlink(s); } } ShowFile(); } int main() { // Memo1.Clear; // Memo2.Clear; MergeSort(); return 0; }