Zamiana wierszy i kolumn w tablicy dwuwymiarowej

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:

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

chcę zamienić na to:

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:

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 :)

3

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

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.
0

Ekstra, bardzo dziękuję!

1
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).

0

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

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:

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;
 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:

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;
 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

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