Nadesłany przez Karol Kokoszka, 28 sierpnia 2005 01:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
nsort_d/nSort.pas:
//sortowanie przez laczenie naturalne //www.algorytm.org //(c)2005 Karol Kokoszka program sortowanieZ; uses crt; type tape_ = record tape : file of byte; bufor : byte; endOfFile: boolean; end; var T: array[0..2] of tape_; {//////////////////////////////////////////////////////////////// //////////////////// operacje na plikach //////////////////////} procedure assign_(var x: tape_; s: string); begin assign(x.tape, s); end; procedure reset_(var x: tape_); begin reset(x.tape); if eof(x.tape) then x.endOfFile:=true else begin read(x.tape, x.bufor); x.endOfFile:=false; end; end; procedure close_(var x: tape_); begin close(x.tape); end; function eof_(var x: tape_): boolean; begin eof_:=x.endOfFile; end; function getBuffer(var x: tape_): byte; begin getBuffer:=x.bufor; end; procedure read_(var x: tape_; var y: byte); begin y:=x.bufor; if eof(x.tape) then begin x.endOfFile:=true end else begin read(x.tape, x.bufor); x.endOfFile:=false; end; end; {///////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////} procedure divFiles(var f1, f2, f3: tape_); var tmp: byte; inWhile: boolean; actFile: ^tape_; begin reset_(f1); rewrite(f2.tape); rewrite(f3.tape); actFile:=@f2; while not eof_(f1) do begin read_(f1, tmp); inWhile:=false; while not eof_(f1) and (getBuffer(f1)>=tmp) do begin write(actFile^.tape, tmp); read_(f1, tmp); end; write(actFile^.tape, tmp); if actFile=@f2 then actFile:=@f3 else actFile:=@f2; end; close_(f1); close(f2.tape); close(f3.tape); end; procedure intBlocks(var f1, f2, f3: tape_); var tmp2, tmp3: byte; end2, end3: boolean; begin end2:=eof_(f2); end3:=eof_(f3); while (not eof_(f2)) and (not eof_(f3)) and (not end2) and (not end3) do begin if getBuffer(f2)<getBuffer(f3) then begin read_(f2, tmp2); write(f1.tape, tmp2); end2:=(getBuffer(f2)<tmp2) or eof_(f2); end else begin read_(f3, tmp3); write(f1.tape, tmp3); end3:=(getBuffer(f3)<tmp3) or eof_(f3); end; end; while not end2 do begin read_(f2, tmp2); write(f1.tape, tmp2); end2:=(getBuffer(f2)<tmp2) or eof_(f2); end; while not end3 do begin read_(f3, tmp3); write(f1.tape, tmp3); end3:=(getBuffer(f3)<tmp3) or eof_(f3); end; end; function mergeFiles(var f1, f2, f3: tape_): boolean; var j: byte; begin reset_(f2); reset_(f3); rewrite(f1.tape); j:=0; while (not eof_(f2)) or (not eof_(f3)) do begin if j<2 then inc(j); intBlocks(f1, f2, f3); end; close_(f2); close_(f3); close(f1.tape); if j<=1 then mergeFiles:=true else mergeFiles:=false; end; procedure printFile(var f: tape_); var tmp: byte; begin reset_(f); while not eof_(f) do begin read_(f, tmp); write(tmp, ' '); end; close_(f); writeln; end; begin if ParamCount<2 then begin writeln('Nie podano nazwy pliku do sortowania ani partycji na pliki tymczasowe....'); writeln('Przyklad: nSort c:\windows\win.com d:\'); end else begin assign_(T[0], ParamStr(1)); assign_(T[1], ParamStr(2) + 'file.000'); assign_(T[2], ParamStr(2) + 'file.001'); repeat divFiles(T[0], T[1], T[2]); until mergeFiles(T[0], T[1], T[2]); end; end.