Mục lục bài họcĐang ở d04-b3
Two-Dimensional Arrays
An array of arrays
In Java a 2D array is really an array whose elements are arrays. For int[][] g = new int[3][4];:
g.length → 3 number of ROWS g[0].length → 4 number of COLUMNS in row 0 g[r][c] → element at row r, column c
The first index is always the row. On the AP exam all 2D arrays are rectangular, so every row has the same length and g[0].length is a safe column count — but writing g[r].length in the inner loop is always correct and costs nothing.
Row-major traversal
for (int r = 0; r < g.length; r++) {
for (int c = 0; c < g[r].length; c++) {
System.out.print(g[r][c]);
}
}
for (int[] row : g) { // each row is an int[]
for (int v : row) { // each v is an int
System.out.print(v);
}
}Swapping the two loop headers gives column-major order, which visits the same cells in a different order — the difference matters as soon as you print, or stop early.
Mảng hai chiều là mảng của những mảng. Với int[][] g = new int[3][4]; thì g.length là số hàng (3) và g[0].length là số cột (4). Chỉ số đầu luôn luôn là hàng: g[r][c] đọc là “hàng r, cột c”. Đảo hai chỉ số vẫn biên dịch được nếu số hàng và số cột bằng nhau, nên đây là loại lỗi chỉ lộ ra ở kết quả sai chứ không ở màn hình đỏ.
Duyệt theo hàng là mặc định: vòng ngoài chạy hàng, vòng trong chạy cột. Đổi chỗ hai vòng lặp thì thành duyệt theo cột — vẫn thăm đủ mọi ô, nhưng thứ tự khác. Thứ tự chỉ vô hại khi ta cộng dồn tất cả; hễ có in ra, có dừng sớm, hay có ghi vào một mảng khác, thứ tự lập tức thành nội dung của câu trả lời.
Vòng for-each lồng nhau viết ngắn hơn nhưng phải khai đúng kiểu: vòng ngoài lấy ra một int[] (nguyên một hàng), vòng trong mới lấy ra int. Dạng này chỉ để đọc — muốn ghi vào ô, hoặc muốn biết mình đang ở hàng nào cột nào, thì bắt buộc quay về vòng lặp có chỉ số.
Đề AP luôn cho mảng chữ nhật (mọi hàng dài bằng nhau), nhưng viết g[r].length ở vòng trong thì không bao giờ sai, kể cả với mảng răng cưa.
g[r][2]. Viết nhầm thành g[2][c] là đang cộng hàng 2 — hai kết quả đều là số hợp lệ, nên không có gì báo cho ta biết là đã lấy nhầm.Viết phương thức trả về mảng một chiều chứa tổng của từng cột trong mảng hai chiều chữ nhật int[][] g.
public static int[] tongCot(int[][] g) {
int[] kq = new int[g[0].length]; // dài bằng SỐ CỘT
for (int c = 0; c < g[0].length; c++) {
for (int r = 0; r < g.length; r++) {
kq[c] += g[r][c];
}
}
return kq;
}Ba chỗ dễ sai, xử lý từng chỗ. Một: độ dài mảng kết quả là số cột g[0].length, không phải số hàng — có bao nhiêu cột thì có bấy nhiêu tổng. Hai: bên trong phải là g[r][c], giữ nguyên thứ tự hàng-cột dù vòng ngoài đang chạy cột. Ba: kq mới tạo đã được điền sẵn số 0, nên cộng dồn thẳng vào là an toàn, không cần gán khởi tạo.
Với {{1,2,3},{4,5,6},{7,8,9}} phương thức trả về {12, 15, 18}.
g[c][r] thay vì g[r][c]. Với mảng vuông nó chạy trơn tru và trả về một con số trông rất hợp lý, nên không ai phát hiện cho tới lúc chấm. Cách chặn: đặt tên biến lặp là r và c chứ đừng dùng i, j — mắt nhìn g[c][r] sẽ thấy sai ngay, còn nhìn g[j][i] thì không. Bẫy thứ hai: dùng g.length làm số cột. Nhớ một câu — g.length đếm hàng, thêm một cặp ngoặc vuông mới ra cột.g.length là số hàng, g[0].length là số cột. Duyệt theo hàng là mặc định; đảo hai vòng lặp là đổi thứ tự thăm chứ không đổi tập hợp ô được thăm.Đọc xong rồi — làm thử ngay
Bài tập của chương Unit 4 — Data Collections gồm 14 câu trắc nghiệm và 8 đề tự luận. Đáp án hiện ngay khi chọn, miễn phí.