Zamiana wierszy i kolumn w tablicy dwuwymiarowej

Zamiana wierszy i kolumn w tablicy dwuwymiarowej
KA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 701
0

Hej,
biorę się za programowanie średnio co pół roku dlatego ciągle borykam się z podstawowymi problemami.

Mam tablicę dwuwymiarową i chciałbym przerzucić jej kolumny z kolumnami i wiersze z wierszami (odwrócić o 180 stopni). Dokładnie to znaczy, że to:

Kopiuj
A4 B4 C4 D4 
A3 B3 C3 D3 
A2 B2 C2 D2 
A1 B1 C1 D1 

chcę zamienić na to:

Kopiuj
D1 C1 B1 A1 
D2 C2 B2 A2 
D3 C3 B3 A3 
D4 C4 B4 A4

oczywiście udało mi się to osiągnąć robiąc tak:

Kopiuj
for i:=0 to 3 do
    for j:=0 to 1 do
    begin
      tmp:=a[j,i];
      a[j,i]:=a[3-j,i];
      a[3-j,i]:=tmp;
    end;
    
for i:=0 to 3 do
    for j:=0 to 1 do
    begin
      tmp:=a[i,j];
      a[i,j]:=a[i,3-j];
      a[i,3-j]:=tmp;
    end;    

https://rextester.com/ABNTKC95084

Ale mam wrażenie, że to jest mega rozwlekle napisane i dałoby się to zrobić za jednym zamachem. Nie jestem jednak w stanie sobie tego wyobrazić. Czy moje rozwiązanie jest ok czy jednak dałoby się to skrócić?

Proszę o pomoc :)

CL
  • Rejestracja: dni
  • Ostatnio: dni
3

Zależy czy Twoja macierz jest symetryczna czy nie. Jeśli masz symetryczną można zrobić tak:
https://rextester.com/FES46529

Kopiuj
program matrix;
type
   TMy_arr = array of array of string;
  

function ArrayRotation(arr : TMy_arr): TMy_arr;
var
  i,j:integer;
begin
setlength(ArrayRotation, high(arr) + 1, high(arr[low(arr)]) + 1);
for i:=low(arr) to high(arr) do
    for j:=low(arr[low(arr)]) to high(arr[low(arr)]) do
      ArrayRotation[high(arr) - i, high(arr[low(arr)]) - j] := arr[i,j];
end;
   
var
  a:TMy_arr;
  i,j:integer;

begin
setlength(a, 4, 4);
a[0,0]:='A4';a[0,1]:='B4';a[0,2]:='C4';a[0,3]:='D4';
a[1,0]:='A3';a[1,1]:='B3';a[1,2]:='C3';a[1,3]:='D3';
a[2,0]:='A2';a[2,1]:='B2';a[2,2]:='C2';a[2,3]:='D2';
a[3,0]:='A1';a[3,1]:='B1';a[3,2]:='C1';a[3,3]:='D1';

for i:=0 to 3 do
begin
writeLn('');
    for j:=0 to 3 do
        write(a[i,j]+' ');
end;

writeLn('');
writeLn('');

a := ArrayRotation(a);

for i:=low(a) to high(a) do
begin
writeLn('');
    for j:=low(a[low(a)]) to high(a[low(a)]) do
      write(a[i,j]+' ');
end;
end.
KA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 701
0

Ekstra, bardzo dziękuję!

flowCRANE
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Tuchów
  • Postów: 12270
1
Kopiuj
for X := 0 to 1 do
  for Y := 0 to 3 do
  begin
    Temp := AMyArray[X, Y];
    AMyArray[X, Y] := AMyArray[3 - X, 3 - Y];
    AMyArray[3 - X, 3 - Y] := Temp;
  end;

Sposób iteracyjny, dla wejściowej macierzy o parzystej liczbie wierszy. Użyłem hardkodowanych liczb, żebyś wiedział jak to działa bez debugowania. Cały przykład tutaj: https://ideone.com/S63noy

Jeśli macierz wejściowa ma nieparzystą liczbę wierszy (liczba kolumn nie ma znaczenia) to potrzebna jest jeszcze jedna osobna pętla (pod tymi zagnieżdżonymi), która odwróci dane w środkowym wierszu.


W ramach wyjaśnienia – liczba 0 to dolny, a 3 to góry indeks zakresu. Natomiast 1 bierze się z dzielenia indeksu ostatniej komórki w wierszu na 2 bez reszty (bez reszty).

KA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 701
0

Dokładnie o coś takiego mi chodziło. Dzięki!

flowCRANE
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Tuchów
  • Postów: 12270
2

W razie czego niżej podaję nieco bardziej uniwersalne przykłady algorytmów iteracyjnych. Niestety ideone ma starą wersję FPC, co uniemożliwia kompilację tych przykładów, więc wrzuciłem je do naszego pastebin. Kod napisałem nieco inaczej, używając prostych helperów, tak aby był czytelny. W każdym razie to tylko dla podglądu, bo właściwa metoda rotująca powinna przyjmować otwartą macierz.


Przykład dla macierzy o parzystym rozmiarze – https://4programmers.net/Pastebin/10018:

Kopiuj
procedure Rotate180(var AMyArray: TMyArray);
var
  X, Y: Integer;
begin
  for X := TMyRange.Low to TMyRange.Mid do
    for Y := TMyRange.Low to TMyRange.High do
      AMyArray.Swap(X, Y, TMyRange.High - X, TMyRange.High - Y);
end;
Kopiuj
 A6 B6 C6 D6 E6 F6
 A5 B5 C5 D5 E5 F5
 A4 B4 C4 D4 E4 F4
 A3 B3 C3 D3 E3 F3
 A2 B2 C2 D2 E2 F2
 A1 B1 C1 D1 E1 F1

 F1 E1 D1 C1 B1 A1
 F2 E2 D2 C2 B2 A2
 F3 E3 D3 C3 B3 A3
 F4 E4 D4 C4 B4 A4
 F5 E5 D5 C5 B5 A5
 F6 E6 D6 C6 B6 A6

Przykład dla macierzy o nieparzystym rozmiarze – https://4programmers.net/Pastebin/10019:

Kopiuj
procedure Rotate180(var AMyArray: TMyArray);
var
  X, Y: Integer;
begin
  for X := TMyRange.Low to TMyRange.Mid - 1 do
    for Y := TMyRange.Low to TMyRange.High do
      AMyArray.Swap(X, Y, TMyRange.High - X, TMyRange.High - Y);

  for Y := TMyRange.Low to TMyRange.Mid - 1 do
    AMyArray.Swap(TMyRange.Mid, Y, TMyRange.Mid, TMyRange.High - Y);
end;
Kopiuj
 A7 B7 C7 D7 E7 F7 G7
 A6 B6 C6 D6 E6 F6 G6
 A5 B5 C5 D5 E5 F5 G5
 A4 B4 C4 D4 E4 F4 G4
 A3 B3 C3 D3 E3 F3 G3
 A2 B2 C2 D2 E2 F2 G2
 A1 B1 C1 D1 E1 F1 G1

 G1 F1 E1 D1 C1 B1 A1
 G2 F2 E2 D2 C2 B2 A2
 G3 F3 E3 D3 C3 B3 A3
 G4 F4 E4 D4 C4 B4 A4
 G5 F5 E5 D5 C5 B5 A5
 G6 F6 E6 D6 C6 B6 A6
 G7 F7 E7 D7 C7 B7 A7

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.