[Algorytmy] Sortowanie linii w pliku

Awatar użytkownika
Mariusz M
Użytkownik
Użytkownik
Posty: 6908
Rejestracja: 25 wrz 2007, o 01:03
Płeć: Mężczyzna
Lokalizacja: 53°02'N 18°35'E
Podziękował: 2 razy
Pomógł: 1246 razy

[Algorytmy] Sortowanie linii w pliku

Post autor: Mariusz M »

Plik jest tekstowy a w liniach są łańcuchy

Znalazłem taki pseudokod łączenia plików

Kod: Zaznacz cały

Załóżmy że bloki zostały rozłożone na pliki P_{0} i P_{1} Pliki P_{2} i P{3} są początkowo puste
i_{1}:=0; i_{2}:=1; {numery plików wejściowych , tzn. otwartych do czytania}
j_{1}:=2; j_{2}:=3; {numery plików wyjściowych , tzn. otwartych do pisania}
while (jest wiecej niz jeden blok) do 
     (a) scal pierwszy blok na P_{i_1} z pierwszym blokiem na P_{i_2} i powstający blok 
          zapisz na P_{j_1}
     (b) scal następny blok na P_{i_1} z następnym blokiem na P_{i_2} i powstający blok 
          zapisz na P_{j_2}
     (c) powtarzaj kroki (a) i (b) (kładąc powstające bloki na przemian na pliki P_{j_1} i P_{j_2}),
          aż zostanie osiągnięty koniec plików P_{i_{1}} i P_{i_{2}}
     (d) przewiń wszystkie pliki do początku;dodaj liczbę 2 mod 4 do i_{1}, i_{2}, j_{1},j_{2}
          odwracając w ten sposób rolę plików wejściowych i wyjściowych
Powyższy pseudokod pochodzi z książki Diksa i Ryttera

Algorytmy sortowania zamieszczone u Cormena dość łatwo zapisać w języku programowania
jednak on ograniczył się tylko do sortowania tablic

Aby zmniejszyć liczbę iteracji można utworzyć początkowe bloki sortując linie w dostępnej dla nas
pamięci RAM
Preferowane jest sortowanie stogowe bo nie używa rekurencji, sortuje w miejscu
a także nie zwolni do \(\displaystyle{ O\left( n^2\right)}\)

Mamy dostępne takie operacje na plikach jak

Sprawdzenie błędów otwarcia pliku
Otwarcie pliku w trzech trybach (do czytania , do pisania , do dopisywania)
Sekwencyjne czytanie pliku
Sekwencyjne pisanie do pliku
Sprawdzanie czy osiągnięto koniec pliku
Zamknięcie pliku
Usunięcie pliku


Jak zapisać ten algorytm w języku programowania takim jak Pascal czy C

-- 5 lutego 2017, 13:23 --

Znalazłem też kod takiej procedury scalającej

Kod: Zaznacz cały

procedure SimpleMergeSort (name:string);
var
		k, i, j, kol, tmp:longint;
		a1, a2:string;
		f, f1, f2:text;
begin
	kol := 0;
	assign(f,name);
	assign(f1,'f01.txt');
	assign(f2,'f02.txt');
	{I-}
		reset(f);
	{I+}

    if ioresult<>0 then
		writeln('Blad otwarcia pliku')
	else
	begin
		reset(f);
		while ( not eof(f) ) do
		begin
			readln(f,a1);
			kol:=kol+1;
		end;
		close(f);
	end;
	k := 1;
	while ( k < kol ) do
	begin
		reset(f);
		rewrite(f1);
		rewrite(f2);
		if ( not eof(f) ) then readln(f,a1);
		while ( not eof(f) ) do
		begin
			i:=0;
			while((i < k) and not eof(f)) do
			begin
				writeln(f1,a1);
				readln(f,a1);
				i:=i+1;
			end;
			j:=0;
			while ((j < k) and not eof(f)) do
			begin
				writeln(f2,a1);
				readln(f,a1);
				j:=j+1;
			end;
		end;
		close(f2);
		close(f1);
		close(f);


		rewrite(f);
		reset(f1);
		reset(f2);

		if ( not eof(f1) ) then readln(f1,a1);
		if ( not eof(f2) ) then readln(f2,a2);
		while ( (not eof(f1)) and (not eof(f2))) do
		begin
			i := 0;
			j := 0;
			while ( (i < k) and (j < k) and (not eof(f1)) and (not eof(f2))) do
				begin
					if ( a1 < a2 ) then
					begin
						writeln(f,a1);
						readln(f1,a1);
						i:=i+1;
					end
					else
					begin
						writeln(f,a2);
						readln(f2,a2);
						j:=j+1;
					end;
				end;
				while ( (i < k) and not eof(f1) ) do
				begin
					writeln(f,a1);
					readln(f1,a1);
					i:=i+1;
				end;
				while ( (j < k) and not eof(f2) ) do
				begin
					writeln(f,a2);
					readln(f2,a2);
					j:=j+1;
				end;
			end;
			while ( not eof(f1) ) do
			begin
				writeln(f,a1);
				readln(f1,a1);
			end;
			while ( not eof(f2) ) do
			begin
				writeln(f,a2);
				readln(f2,a2);
			end;
			close(f2);
			close(f1);
			close(f);
			k :=k*2;
		end;
		erase(f1);
		erase(f2);
end;

Jednak nie scala poprawnie plików
qwertghjio
Użytkownik
Użytkownik
Posty: 66
Rejestracja: 5 paź 2016, o 14:54
Płeć: Mężczyzna
Lokalizacja: pzn
Podziękował: 3 razy

[Algorytmy] Sortowanie linii w pliku

Post autor: qwertghjio »

Jaki wynik otrzymasz gdy wpiszesz do plików odpowiednio wiersze 1 2 3 i 1 2 ?
Awatar użytkownika
Mariusz M
Użytkownik
Użytkownik
Posty: 6908
Rejestracja: 25 wrz 2007, o 01:03
Płeć: Mężczyzna
Lokalizacja: 53°02'N 18°35'E
Podziękował: 2 razy
Pomógł: 1246 razy

[Algorytmy] Sortowanie linii w pliku

Post autor: Mariusz M »

Chodzi o algorytm przedstawiony w książce Diksa czy o
proste scalanie ?

Jeśli chodzi o algorytm przedstawiony w książce Diksa to nie mam pomysłu jak zapisać
go w języku programowania

Proste scalanie gubi linie , wygląda na to że nie kopiuje całego pliku
qwertghjio
Użytkownik
Użytkownik
Posty: 66
Rejestracja: 5 paź 2016, o 14:54
Płeć: Mężczyzna
Lokalizacja: pzn
Podziękował: 3 razy

[Algorytmy] Sortowanie linii w pliku

Post autor: qwertghjio »

Ten algorytm z tego co zrozumiałem, to tylko scala wiersze z sobą. Czyli 1 z 2 i 3, potem 2 z 1 i 3, 3 z 1 2. Wiersze to te bloczki do scalenia.
Awatar użytkownika
Mariusz M
Użytkownik
Użytkownik
Posty: 6908
Rejestracja: 25 wrz 2007, o 01:03
Płeć: Mężczyzna
Lokalizacja: 53°02'N 18°35'E
Podziękował: 2 razy
Pomógł: 1246 razy

[Algorytmy] Sortowanie linii w pliku

Post autor: Mariusz M »

Scalanie proste

1. Procedura zlicza linie w pliku
(problem będzie gdy liczba linii wyjdzie poza zakres typu integer)
2. Procedura kopiuje serie z pliku f do dwóch plików f1 oraz f2
3. Procedura pobiera serie z plików f2 oraz f2, scala je i zapisuje je do pliku f

Te trzy punkty są realizowane w jednej procedurze
jednak wygląda na to że nie wszystkie linie są kopiowane


Algorytm umieszczony w książce Diksa Ryttera zapowiada się ciekawiej-- 28 lutego 2017, 02:48 -- ... danych.pdf

Próbowałem przepisać kod tego kolesia ale nie działa poprawnie
Poza tym w C obsługa tablic znakowych nie jest wygodna jak np w Pascalu
ODPOWIEDZ