Studiuję ten fragment kodu podczas obracania macierzy NxN; Wiele razy śledziłem program i trochę rozumiem, jak zachodzi faktyczna rotacja. Obraca on najpierw rogi i elementy za rogami w kierunku zgodnym z ruchem wskazówek zegara. Po prostu nie rozumiem kilku linii, a kod nadal nie jest "napędzany domem" w moim mózgu, że tak powiem. Proszę pomóż. Obracam go o 90 stopni, biorąc pod uwagę macierz 4x4 jako przykład śledzenia.Obracanie macierzy dwuwymiarowej o 90 stopni
[1][2][3][4]
[5][6][7][8]
[9][0][1][2]
[3][4][5][6]
staje
[3][9][5][1]
[4][0][6][2]
[5][1][7][3]
[6][2][8][4]
public static void rotate(int[][] matrix, int n){
for(int layer=0; layer < n/2; ++layer) {
int first=layer; //It moves from the outside in.
int last=n-1-layer; //<--This I do not understand
for(int i=first; i<last;++i){
int offset=i-first; //<--A bit confusing for me
//save the top left of the matrix
int top = matrix[first][i];
//shift left to top;
matrix[first][i]=matrix[last-offset][first];
/*I understand that it needs
last-offset so that it will go up the column in the matrix,
and first signifies it's in the first column*/
//shift bottom to left
matrix[last-offset][first]=matrix[last][last-offset];
/*I understand that it needs
last-offset so that the number decreases and it may go up the column (first
last-offset) and left (latter). */
//shift right to bottom
matrix[last][last-offset]=matrix[i][last];
/*I understand that it i so that in the next iteration, it moves down
the column*/
//rightmost top corner
matrix[i][last]=top;
}
}
}
że zgadzają się, że jest łatwiejszy sposób, ale nie byłoby znacznie mniej wydajne dla małych matryc? Transponowanie macierzy przenosi elementy do właściwego wiersza, ale niewłaściwą kolumnę, która wymaga późniejszej korekty. Algorytm OP przesuwa elementy do poprawnego wiersza i kolumny przy pierwszym uruchomieniu (w sumie mniej przydziałów). Ignoruję lokalność w tym porównaniu, ponieważ nie jest to problemem dla małych macierzy. W przypadku dużych macierzy możemy chcieć zmienić kolejność przypisań w algorytmie OP i zoptymalizować transpozycję w tym algorytmie. –
@Nathan: Obie metody wykonują taką samą liczbę ładowań pamięci i przypisań pamięci (pamiętaj, że tymczasowa zamiana będzie zwykle rejestrem, a także "szczytem" w kodzie OP). Ten jest prosty i czytelny i prawdopodobnie bardziej wydajny niż proponowany, który nie odnosi się do danych w sposób ciągły. –