1. Mảng hai chiều

Thêm một sự thật thú vị về mảng. Mảng không chỉ là một chiều (tuyến tính). Chúng cũng có thể là hai chiều.

Điều đó có nghĩa là gì, bạn yêu cầu?

Điều này có nghĩa là các ô của mảng có thể biểu thị không chỉ một cột (hoặc hàng) mà còn cả một bảng hình chữ nhật.

int[][] name = new int[width][height];

Trong đó name là tên của biến mảng, width là chiều rộng của bảng (tính theo ô) và height là chiều cao của bảng. Ví dụ:

int[][] data = new int[2][5];
data[1][1] = 5;
Chúng tôi tạo một mảng hai chiều: 2 cột và 5 hàng.
Viết 5 vào ô (1, 1).

Đây là cách nó sẽ trông trong bộ nhớ:

mảng hai chiều

Nhân tiện, bạn cũng có thể sử dụng khởi tạo nhanh cho mảng hai chiều:

// Lengths of months of the year in each quarter
int[][] months = { {31, 28, 31}, {30, 31, 30}, {31, 31, 30}, {31, 30, 31} };

Có rất nhiều nơi mà bạn, với tư cách là một lập trình viên, có thể cần một mảng hai chiều. Mảng hai chiều là nền tảng của hầu hết mọi trò chơi trên bàn cờ, ví dụ như cờ vua, cờ đam, tic-tac-toe và trận chiến trên biển:

mảng hai chiều 2

Mảng hai chiều là lựa chọn hoàn hảo cho cờ vua hoặc trận chiến trên biển. Chúng ta chỉ cần số dạng tọa độ ô. Không phải 'cầm đồ e2-e4', mà là 'cầm đồ (5,2) -> (5,4)'. Nó sẽ còn dễ dàng hơn cho bạn với tư cách là một lập trình viên.


2. Sắp xếp các phần tử trong mảng: (x,y) hoặc (y,x)

Nhân tiện, có một vấn đề nan giải thú vị ở đây:

Khi chúng ta tạo một mảng bằng cách sử dụng new int[2][5];, chúng ta có một bảng gồm 'hai hàng và 5 cột ' hay là 'hai cột và 5 hàng '?" Nói cách khác, trước tiên chúng ta chỉ định chiều rộng và sau đó là chiều cao... hay ngược lại, trước tiên là chiều cao và sau đó là chiều rộng Chà, như chúng ta thường nói, mọi thứ ở đây không đơn giản như vậy.

Hãy bắt đầu với câu hỏi mảng được lưu trữ trong bộ nhớ như thế nào .

Tất nhiên, bộ nhớ máy tính không thực sự có ma trận trong đó: mỗi vị trí trong bộ nhớ có một địa chỉ số tuần tự: 0, 1, 2, ... Trong trường hợp của chúng tôi, chúng tôi nói về ma trận 2 × 5, nhưng trong bộ nhớ nó chỉ là 10 ô liên tiếp, không có gì hơn. Không có gì cho biết vị trí của các hàng và cột.

Đối số ủng hộ "chiều rộng x chiều cao".

Lập luận ủng hộ cách tiếp cận này là mọi người đều học toán ở trường, nơi họ biết rằng các cặp tọa độ được viết là 'x' (tức là trục hoành) và sau đó là 'y' (chiều dọc). Và đây không chỉ là tiêu chuẩn của trường học — nó là tiêu chuẩn được chấp nhận rộng rãi trong toán học. Như họ nói, bạn không thể tranh luận với toán học. Là vậy sao? Chiều rộng đầu tiên và sau đó là chiều cao?

Lập luận ủng hộ "chiều cao x chiều rộng".

Ngoài ra còn có một đối số thú vị được đưa ra cho vị trí này: khởi tạo nhanh các mảng hai chiều. Thật vậy, nếu chúng ta muốn khởi tạo mảng của mình, thì chúng ta có thể viết mã như sau:

// Matrix of important data
int[][] matrix = { {1, 2, 3, 4, 5}, {1, 2, 3, 4, 5} };

Bạn không nhận thấy bất cứ điều gì? Nếu chúng ta có cái này thì sao?

// Matrix of important data
int[][] matrix = {
  {1, 2, 3, 4, 5},
  {1, 2, 3, 4, 5}
};

Nếu chúng ta ghi dữ liệu của mình vào từng dòng mã, thì chúng ta sẽ nhận được một ma trận có 2 hàng và 5 cột.

dòng dưới cùng

Chúng ta có thể nói gì? Tùy thuộc vào bạn để quyết định cái nào thuận tiện hơn cho bạn. Điều quan trọng nhất là tất cả các lập trình viên làm việc trong cùng một dự án đều tuân theo cùng một cách tiếp cận.

Nếu bạn làm việc trên một dự án có mã có nhiều mảng hai chiều được khởi tạo, thì rất có thể mọi thứ ở đó sẽ dựa trên quá trình khởi tạo dữ liệu nhanh, tức là bạn sẽ có 'chiều cao x chiều rộng' tiêu chuẩn.

Nếu bạn đủ may mắn để tìm thấy chính mình trong một dự án liên quan đến nhiều toán học và làm việc với tọa độ (ví dụ: công cụ trò chơi), thì mã rất có thể sẽ áp dụng phương pháp 'rộng x cao'.


3. Cách sắp xếp mảng hai chiều

Và bây giờ bạn sẽ học cách các mảng hai chiều thực sự được sắp xếp. Sẵn sàng?

Mảng hai chiều thực chất là mảng của mảng!

Nói cách khác, nếu trong trường hợp của một mảng thông thường, một biến mảng lưu trữ một tham chiếu đến một vùng chứa lưu trữ các phần tử của mảng, thì trong trường hợp của mảng hai chiều, tình huống sẽ bùng nổ một chút: biến mảng hai chiều lưu trữ một tham chiếu đến vùng chứa lưu trữ tham chiếu đến mảng một chiều. Tốt hơn là xem nó hoạt động một lần thay vì cố gắng giải thích nó hàng trăm lần:

Mảng hai chiều được sắp xếp như thế nào

bên trái , chúng ta có một biến mảng hai chiều, lưu trữ một tham chiếu đến một đối tượng mảng hai chiều. bên trongở giữa, chúng ta có một đối tượng mảng hai chiều có các ô lưu trữ mảng một chiều, là các hàng của mảng hai chiều. Và ở bên phải , bạn có thể thấy bốn mảng một chiều — các hàng của mảng hai chiều của chúng ta.

Đây là cách mảng hai chiều thực sự hoạt động. Và cách tiếp cận này mang lại cho lập trình viên Java một số lợi thế:

Đầu tiên , vì 'vùng chứa của các vùng chứa' lưu trữ các tham chiếu đến 'mảng các hàng', nên chúng ta có thể hoán đổi các hàng rất nhanh chóng và dễ dàng. Để có được 'vùng chứa của các vùng chứa', bạn chỉ cần chỉ định một chỉ mục thay vì hai chỉ mục. Ví dụ:

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

Mã này cho phép bạn trao đổi hàng:

// Matrix of important data
int[][] matrix = {
  {1, 2, 3, 4, 5},
  {5, 4, 3, 2, 1}
};

int[] tmp = matrix[0];
matrix[0] = matrix[1];
matrix[1] = tmp;
Mảng hai chiều lưu





matrix[0]trữ tham chiếu đến hàng đầu tiên.
Chúng tôi trao đổi các tài liệu tham khảo.

Kết quả là, matrixmảng trông như thế này:
{
  {5, 4, 3, 2, 1},
  {1, 2, 3, 4, 5}
};

Nếu bạn tham chiếu đến một ô của mảng hai chiều, nhưng bạn chỉ chỉ định một chỉ mục sau tên của mảng, thì bạn đang đề cập đến một vùng chứa các vùng chứa có các ô lưu trữ các tham chiếu đến các mảng một chiều thông thường.