1. Tablice dwuwymiarowe

I jeszcze jeden interesujący fakt dotyczący tablic. Tablice są nie tylko liniowe, ale także dwuwymiarowe.

A co to znaczy, pytasz?

Oznacza to, że komórki tablicy mogą być reprezentowane nie tylko jako kolumna (lub wiersz), ale także jako prostokątna tabela.

int[][] Nazwa = new int[ширина][высота];

Gdzie nazwa to nazwa zmiennej tablicowej, szerokość to szerokość tabeli (w komórkach), a wysokość to wysokość tabeli. Przykład:

int[][] data = new int[2][5];
data[1][1] = 5;
Tworzymy dwuwymiarową tablicę: dwie kolumny i 5 wierszy.
W komórce (1,1) piszemy 5.

Oto jak by to wyglądało w pamięci:

tablice 2D

Nawiasem mówiąc, w przypadku tablic dwuwymiarowych można również użyć szybkiej inicjalizacji:

// длины месяцев года поквартально
int[][] months = { {31, 28, 31}, {30, 31, 30}, {31, 31, 30}, {31, 30, 31} };

Jest tak wiele miejsc, w których jako programista potrzebujesz tablicy dwuwymiarowej. Implementacją niemal każdej gry planszowej jest gotowa dwuwymiarowa tablica: Szachy, Warcaby, Kółko i krzyżyk, Bitwa morska:

tablice 2D 2

Pole gry „Szachy” lub „Bitwa morska” jest takie, że idealnie pasuje do dwuwymiarowych tablic, tylko liczby będą musiały być użyte jako współrzędne komórki. Nie „pionek e2 -> e4”, ale „pionek (4,1) -> (4,3)”. Tobie jako programiście będzie jeszcze łatwiej.


2. Układ elementów w tablicach: (x,y) lub (y,x)

Tutaj, nawiasem mówiąc, pojawia się ciekawy dylemat:

Kiedy tworzymy tablicę new int[2][5]; czy mamy tabelę „dwa wiersze i 5 kolumn ” czy „dwie kolumny i 5 wierszy ”? Innymi słowy, czy najpierw ustawiamy „szerokość”, a następnie „wysokość”, czy nadal najpierw „wysokość”, a następnie „szerokość”? I, jak mówią, nie wszystko jest takie proste.

Zacznijmy od pytania: w jaki sposób ta tabela jest właściwie przechowywana w pamięci?

W samej pamięci komputera nie ma tabel: wszystkie bajty pamięci są ponumerowane jako 0, 1, 2, ... To jest dla nas tabela 2 × 5, ale w pamięci to tylko 10 komórek i to wszystko. Bez separacji, gdzie są wiersze, a gdzie kolumny.

Argument na korzyść hipotezy „szerokość” - „wysokość”.

Nawet w szkole wszyscy byli uczeni, że z pary współrzędnych najpierw wskazuje się „x”, a następnie „y”. I to nie jest tylko norma szkolna - to generalnie norma w matematyce. Jak to mówią, nie można spierać się z królową nauk. Więc? Najpierw „szerokość”, a następnie „wysokość”?

Argument na korzyść hipotezy „wysokość” - „szerokość”.

Jest tu też ciekawy argument, a wynika on z… szybkiej inicjalizacji tablic dwuwymiarowych. W końcu, jeśli chcemy zainicjować naszą tablicę, zapisujemy ten kod jako:

// Важная матрица с данными
int[][] matrix = { {1, 2, 3, 4, 5}, {1, 2, 3, 4, 5} };

Czy coś zauważasz? A jeśli tak:

// Важная матрица с данными
int[][] matrix = {
  {1, 2, 3, 4, 5},
  {1, 2, 3, 4, 5}
};

Jeśli zapiszemy nasze dane linia po linii kodu, otrzymamy tabelę, która ma 2 wiersze i 5 kolumn.

Wyniki

Co możesz powiedzieć? Ty decydujesz, co jest dla Ciebie wygodniejsze. Najważniejsze jest to, że wszyscy programiści pracujący nad tym samym projektem powinni stosować to samo podejście.

Jeśli pracujesz nad projektem, w którym w kodzie jest dużo inicjowanych tablic dwuwymiarowych, to najprawdopodobniej wszystko zacznie się od szybkiej inicjalizacji danych i będzie obowiązywał standard „wysokość” - „szerokość”.

Jeśli masz szczęście dostać się do projektu, w którym jest dużo matematyki i pracy ze współrzędnymi (na przykład praca z silnikami gier), najprawdopodobniej zastosują podejście „szerokość” - „wysokość”


3. Układ tablic dwuwymiarowych

A teraz dowiesz się, jak działają tablice dwuwymiarowe. Gotowy?

Tablice dwuwymiarowe to tak naprawdę tablice tablic!

Innymi słowy, jeśli w przypadku zwykłej tablicy „zmienna tablicowa przechowuje odniesienie do kontenera, w którym przechowywane są elementy tablicy”. Z kolei w przypadku tablic dwuwymiarowych sytuacja jest nieco bardziej wybuchowa: zmienna tablicy dwuwymiarowej przechowuje odwołanie do kontenera, który przechowuje odniesienia do tablic jednowymiarowych. Lepiej zobaczyć to raz, niż próbować wyjaśniać to sto razy:

Urządzenie tablic dwuwymiarowych

Po lewej stronie mamy „zmienną tablicową dwuwymiarową”, która przechowuje odniesienie do „obiektu dwuwymiarowej tablicy”. W środku mamy „dwuwymiarowy obiekt tablicowy”, którego komórki przechowują odnośniki do jednowymiarowych tablic – wierszy dwuwymiarowej tablicy. Cóż, po prawej stronie widzisz cztery jednowymiarowe tablice - linie naszej dwuwymiarowej tablicy.

Tak właśnie działają tablice dwuwymiarowe. Takie podejście daje programiście Java kilka korzyści:

Po pierwsze dlatego, że „kontener kontenerów” przechowuje odniesienia do „tablic-łańcuchów”, możemy szybko i łatwo zamienić ciągi znaków. Aby uzyskać dostęp do „kontenera kontenerów”, wystarczy podać jeden indeks zamiast dwóch. Przykład:

int[][] data = new int[2][5];
int[] row1 = data[0];
int[] row2 = data[1];

Za pomocą tego kodu możesz zamienić linie w miejscach:

// Важная матрица с данными
int[][] matrix = {
  {1, 2, 3, 4, 5},
  {5, 4, 3, 2, 1}
};

int[] tmp = matrix[0];
matrix[0] = matrix[1];
matrix[1] = tmp;
Tablica dwuwymiarowa





W matrix[0]mamy odniesienie do pierwszego wiersza.
Wymiana linków.

W rezultacie tablica matrixwygląda następująco:
{
  {5, 4, 3, 2, 1},
  {1, 2, 3, 4, 5}
};

Jeśli odwołujesz się do komórki w tablicy dwuwymiarowej, ale określasz tylko jeden indeks po nazwie tablicy, odnosisz się do kontenera-kontenera, którego komórki przechowują odniesienia do zwykłych tablic jednowymiarowych.