Porządkowanie tablicy dwuwymiarowej ( pierw kolumny, potem wiersze)

0

Witam,

Postanowiłem zrobić taki o to program, który będzie miał za zadanie porządkowanie punktów o współrzędnych (x,y) wpisanych do tablicy dwuwymiarowej.

Udało mi się zrobić porządkowanie kolumn, na pierwszy rzut oka działa.
Jeżeli mogę Was prosić, to żebyście ocenili, co powinienem poprawić, nad czym się zastanowić, wiem, że nie jest to zbyt wyszukany algorytm, no ale na inny nie mogłem wpaść i chciałem prosić o jakieś rady, by coś jeszcze może w tym zmienić.

program porzadkowaniepunktow;
uses crt;
var
tab:array[1..10001,1..3] of longint;
tmp,tmp2:integer;
n:integer;
a,b,z:integer;

procedure wczytajtablice(n:longint);
var i:longint; j:byte;
begin
  for i:=1 to n do
  begin
    for j:=1 to 2 do
    begin
      read(tab[i][j]);
    end;
  end;
end;
procedure porzadkujkolumny(n:integer);
var k,x,y:integer;
begin
  for k:=1 to n do
  begin
    for x:=1 to n-1 do
    begin
    for y:=1 to 1 do
      begin
        if(tab[x][y]>tab[x+1][y]) then
        begin
         tmp:=tab[x][y];
         tmp2:=tab[x][y+1];
         tab[x][y]:=tab[x+1][y];
         tab[x][y+1]:=tab[x+1][y+1];
         tab[x+1][y]:=tmp;
         tab[x+1][y+1]:=tmp2;
        end;
      end;
    end;
  end;
end;
begin
  clrscr;
  REPEAT
  readln(n);
  UNTIL (n>=1) and (n<=10000);
  WczytajTablice(n);
  PorzadkujKolumny(n);
  readln;
  clrscr;
  for a:=1 to n do
  begin
    for b:=1 to 2 do
    begin
     write(tab[a,b], ' ');
    end;
    writeln;
  end;
  readln;
end.



Ponadto, chciałem się spytać, w jaki sposób teraz mogę uporządkować wiersze? Czyli jeżeli mam np. dwa punkty o współrzędnych 1 - (1,2 ) oraz 2 - (1,1), to w jaki sposób to zrobić? Próbowałem robić na tej samej zasadzie, co robiłem porządkowanie kolumn, lecz nie działało to poprawnie.

Pozdrawiam serdecznie i dzięki

#edit w kwestii zmienienia wielkości przyporządkowanym zmiennym, to pobawię się potem, sam nie wiem dlaczego dałem aż takie wielkie.

2

Pierwsze co by wypadało, to zadeklarowanie sobie typu rekordu, posiadającego wszystkie współrzędne jednego punktu, tak aby macierz z punktami była jednowymiarowa - to powinno po pierwsze uprościć zapis, po drugie ułatwi swapa elementów tablicy podczas sortowania; Czyli zadeklaruj sobie typ punktu, np. tak:

type
  TPointRec = packed record
    X, Y, Z: LongInt; // dlaczego nie Integer?
  end;

Nie wiem dlaczego współrzędne muszą być liczbami naturalnymi, w każdym razie mógłbyś użyć typu Integer dla wartości pojedynczych koordynatów;

Po drugie wywal zmienne globalne - nie ucz się ich stosowania, bo to nie jest najlepsze rozwiązanie; Dobrym nawykiem jest ustalanie widoczności zmiennych i stałych tylko tam, gdzie są one wymagane; Dlatego lepiej jest stosować zmienne lokalne oraz przekazywać dane w parametrach procedur czy funkcji; Twoja procedury wczytajtablice i porzadkujkolumny powinny pobierać macierz w parametrze, zarówno do wypełniania, jak i do sortowania;

Po trzecie indeksujesz elementy macierzy od 1, a powinieneś od 0 - to także dobry nawyk, który warto sobie wyrobić, bo w programowaniu wszystko indeksuje się od 0 (oczywiście są wyjątki, ale jest ich niezbyt wiele);

Po czwarte zadeklaruj sobie typy, które posłużą Ci do deklaracji zmiennych; W przypadku dodania kolejnych zmiennych tego samego typu, nie będziesz musiał przepisywać nazwy typu, co będzie uciążliwe przy np. array[1..10001,1..3] of longint;

Po piąte, skorzystaj z macierzy dynamicznych, bo nie wiesz ile punktów chce podać użytkownik; Tutaj zauważysz dlaczego dobrze jest nauczyć się indeksować macierze od 0 - w przypadku macierzy dynamicznych to konieczność, nie możliwość;

Po szóste, dodawaj do kodu puste linie i komentarze - to uczyni kod jeszcze bardziej czytelnym, choć w obecnej postaci jest dobrze sformatowany;


To tyle na wstępie, resztę pozostawiam Tobie do ogarnięcia; Nie jest źle, ale po części wyrobiłeś sobie złe nawyki (zmienne globalne, brak parametrów w procedurach, statyczne i ogromne tablice itd.), z którymi polecam wziąć jak najszybciej rozwód.

2

Po siódme, przekaż do funkcji sortującej adres funkcji porównującej, w tym przypadku aby zrobić inny porządek wystarczy napisać funkcje porównującą:

type
  TPointRec=record
    X, Y, Z: LongInt;
  end;
  TPointList=array of TPointRec;
  TCompare=function(const A,B:TPointRec):Boolean;

function ByX(const A,B:TPointRec):Boolean;
begin
  Result:=(A.X>B.X);
end;

procedure porzadkujkolumny(var Points:TPointList;cmp:TCompare);
var I:Integer;
var T:TPointRec;
begin
   for I=1 to Length(Points)-1 do
   begin
     ...
     if cmp(Points[I-1],Points[I]) then
     begin
       T:=Points[I-1];
       Points[I-1]:=Points[I];
       Points[I]:=T;
     end;
     ...
   end;
end;
0

Dzięki bardzo Panowie za pomoc, jak do tej pory jeszcze nie doszedłem w książce do rekordów, ani nie miałem ich na lekcjach w liceum, dlatego próbowałem wykorzystać to, czego nauczyłem się jak do tego momentu.

Co do ogromnych tablic dynamicznych, rozwiązuje zadania znajdujące się na stronie "młodzieżowej akademii informatycznej" no i właśnie tam jest w zadaniu podane, iż podane może być co najwyżej 10 tysięcy punktów, no ale fakt, jeżeli ktoś poda tylko 4 współrzędne, to reszta będzie nie używana. No bezsens.

Co do typów zmiennych, takie wielkie są, ponieważ w niektórych zadaniach właśnie z tej strony potrzebne są gdzie nie gdzie zadeklarowane zmienne, mogące pomieścić większe wartości niż te 32 tysiące, dlatego trochę na pamięć robione.

Jeszcze raz wielkie dzięki i serdecznie pozdrawiam, na pewno wezmę wszystkie cenne informacje pod uwagę ( czyli wszystkie :) )

1

Rekord do bardzo prosta konstrukcja, a ich obsługa jest tak prosta, jak i obsługa zmiennych typów prostych, tyle że wymaga użycia operatora.; Zobacz jak się ich używa, a nie będzie miał najmniejszego problemu z ich wykorzystaniem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1