JavaRush /Blog Java /Random-VI /Mảng đa chiều

Mảng đa chiều

Xuất bản trong nhóm
Mảng đa chiều - 1

Mảng Java một chiều là gì?

Mảng là một tập hợp có thứ tự các phần tử cùng loại, nguyên thủy hoặc tham chiếu. Thông tin chung về mảng (chủ yếu là một chiều) có thể được tìm thấy trong bài viết “ Mảng trong Java ” và trong khóa học JavaRush . Trong bài viết này chúng ta sẽ nói về mảng có các phần tử là các mảng khác. Mảng như vậy được gọi là đa chiều. Một mảng mà các phần tử của nó là các mảng khác, tức là một mảng các mảng, được gọi là mảng hai chiều. Không phải tất cả các ngôn ngữ đều có mảng đa chiều được cấu trúc theo cách này, nhưng trong Java thì đúng như vậy.

Mảng đa chiều trong Java, Cú pháp chung

Nói chung, mảng đa chiều trong Java trông như thế này:
Data_type[dimension1][dimension2][]..[dimensionN] array_name = new data_type[size1][size2].[sizeN];
Data_typeLoại phần tử trong mảng ở đâu . Có thể là nguyên thủy hoặc tham chiếu (lớp). Số cặp dấu ngoặc có dimensionbên trong là kích thước của mảng (trong trường hợp của chúng tôi - N). array_name— tên mảng size1...sizN— số phần tử trong mỗi chiều của mảng. Khai báo mảng nhiều chiều:
int[][] twoDimArray; //two-dimensional array
String[][][] threeDimArray; //three-dimensional array
double[][][][][] fiveDimArray; // five-dimensional array
Có lẽ tất cả điều này trông rất trừu tượng, vì vậy bây giờ chúng ta hãy chuyển sang các biểu hiện cụ thể của mảng đa chiều - hai chiều và ba chiều. Thực tế là các nhà phát triển Java đôi khi sử dụng mảng hai chiều, ít thường xuyên hơn - mảng ba chiều và thậm chí cả mảng lớn hơn cũng cực kỳ hiếm. Khả năng cao là bạn sẽ không gặp phải chúng.

Mảng đa chiều trong khóa học JavaRush

Trong JavaRush, các mảng “thông thường” được bắt đầu ở cấp độ 7 của nhiệm vụ Cú pháp Java và sau này trong khóa học, chúng sẽ gặp phải nhiều lần. Đôi khi trong suốt khóa học, bạn gặp phải các vấn đề liên quan đến mảng hai chiều (hoặc những vấn đề có thể giải quyết được với sự trợ giúp của chúng). Mảng hai chiều cũng được sử dụng trong công cụ trò chơi của phần đặc biệt “ Trò chơi trên JavaRush ”. Nếu bạn chưa đến đó, hãy xem và tạo một hoặc hai trò chơi. Các điều khoản và điều kiện đi kèm với hướng dẫn chi tiết và sẽ cung cấp đào tạo tuyệt vời về kỹ năng lập trình. Mảng ba chiều có thể được tìm thấy trong trò chơi Space Invaders . Thông qua đó, một tập hợp các khung dành cho hoạt ảnh được chỉ định (và mỗi khung này là một mảng hai chiều). Nếu bạn đã hoàn thành nhiệm vụ JavaSyntax hoặc chỉ cảm thấy tự tin về lập trình Java, hãy thử viết phiên bản trò chơi cổ điển này của riêng bạn.

Mảng Java hai chiều là gì?

Mảng hai chiều trong Java là một mảng gồm nhiều mảng, nghĩa là mỗi ô chứa một tham chiếu đến một mảng. Nhưng sẽ dễ dàng hơn nhiều khi trình bày nó dưới dạng bảng có số hàng nhất định (chiều thứ nhất) và số cột (chiều thứ hai). Mảng hai chiều trong đó tất cả các hàng có số phần tử bằng nhau được gọi là mảng hình chữ nhật.

Khai báo, tạo và khởi tạo mảng hai chiều

Quy trình khai báo và tạo mảng hai chiều gần giống như trong trường hợp mảng một chiều:
int[][] twoDimArray = new int[3][4];
Mảng này có 3 hàng và 4 cột. Kích thước của một mảng hai chiều hình chữ nhật (chúng có thể không phải là hình chữ nhật, xem thêm ở bên dưới), nghĩa là tổng số phần tử có thể được xác định bằng cách nhân số hàng với số cột. Bây giờ nó được khởi tạo (điền) với các giá trị mặc định. Đó là, số không. Hãy điền vào nó những giá trị chúng ta cần.
twoDimArray[0][0] = 5;//write the value 5 into the cell at the intersection of the zero row and zero column
twoDimArray[0][1] = 7; //write the value 7 into the cell at the intersection of the zero row and the first column
twoDimArray[0][2]  = 3;
twoDimArray[0][3] = 17;
twoDimArray[1][0] = 7;
twoDimArray[1][1] = 0;
twoDimArray[1][2] = 1;
twoDimArray[1][3] = 12;
twoDimArray[2][0] = 8;
twoDimArray[2][1] = 1;
twoDimArray[2][2] = 2;
twoDimArray[2][3] = 3;
Giống như mảng một chiều, bạn có thể thực hiện quy trình khởi tạo nhanh hơn:
int [][] twoDimArray = {{5,7,3,17}, {7,0,1,12}, {8,1,2,3}};
Trong cả hai trường hợp, chúng ta sẽ nhận được một mảng hai chiều có ba hàng và bốn cột, chứa đầy các số nguyên. Mảng đa chiều - 2

Hiển thị mảng hai chiều trên màn hình

Cách hợp lý nhất để thực hiện thao tác này là trước tiên xuất ra phần tử dòng 0 theo từng phần tử, sau đó là phần tử thứ hai, v.v. Cách phổ biến nhất để xuất mảng hai chiều trong Java là sử dụng hai vòng lặp lồng nhau.
int [][] twoDimArray = {{5,7,3,17}, {7,0,1,12}, {8,1,2,3}};//declared an array and filled it with elements
for (int i = 0; i < 3; i++) {  //go through the lines
            for (int j = 0; j < 4; j++) {//go through the columns
                System.out.print(" " + twoDimArray[i][j] + " "); //output element
            }
            System.out.println();// line wrap for the visual preservation of the tabular form
        }

Đầu ra nhanh của mảng hai chiều

Cách ngắn nhất để hiển thị danh sách các phần tử của mảng hai chiều trên màn hình là sử dụng phương thức deepToStringlớp Arrays. Ví dụ:
int[][] myArray = {{18,28,18},{28,45,90},{45,3,14}};
System.out.printLn(Arrays.deepToString(myArray));
Kết quả của chương trình là đầu ra như sau: [[18, 28, 18], [28, 45, 90], [45, 3, 14]]

“Độ dài” của mảng hai chiều

Để lấy độ dài của mảng một chiều (tức là số phần tử trong mảng), bạn có thể sử dụng biến length. Nghĩa là, nếu chúng ta xác định một mảng int a[] = {1,2,3}thì phép toán a.lengthtrả về 3. Nhưng nếu chúng ta áp dụng quy trình tương tự cho mảng hai chiều thì sao?
int [][] twoDimArray = {{5,7,3,17}, {7,0,1,12}, {8,1,2,3}};
System.out.println(twoDimArray.length);
Đầu ra: 3 Vậy thao tác này sẽ xuất ra số hàng trong mảng. Làm thế nào để có được số lượng cột? Nếu chúng ta đang xử lý các mảng hai chiều hình chữ nhật (nghĩa là các mảng trong đó tất cả các dòng có cùng độ dài), thì chúng ta có thể áp dụng phép toán twoDimArray[0].lengthhoặc thay vì phần tử 0 (về cơ bản là dòng 0) - bất kỳ phần tử hiện có nào khác. Chúng ta có thể làm điều này vì trong Java, mảng hai chiều là một mảng gồm nhiều mảng và phần tử 0 twoDimArray[0]là một mảng có độ dài 4. Bạn có thể tự kiểm tra điều này.

Ví dụ về sử dụng mảng hai chiều: bàn cờ

Mảng hai chiều có thể được sử dụng để tạo bất kỳ trường hai chiều hữu hạn nào, ví dụ như trong trò chơi và đặc biệt là trong cờ vua. Thật dễ dàng để hình dung bàn cờ như một mảng hai chiều. Bạn có thể “đính kèm” đồ họa vào đây, nhưng bây giờ, hãy xác định một bàn cờ bằng cách sử dụng các ký hiệu và xuất nó ra bảng điều khiển. Mảng đa chiều - 3Ô vuông phía dưới bên trái của bàn cờ được sơn màu đen, ô tiếp theo màu trắng, ô phía trên cũng vậy. Vì vậy, màu sắc sẽ thay đổi mỗi khi bạn di chuyển đến ô liền kề bên cạnh. Để đặt màu cờ không phải theo cách thủ công mà sử dụng thuật toán, bạn có thể sử dụng kiểm tra chẵn lẻ: nếu tổng của chỉ số hàng và cột là chẵn hoặc bằng 0 thì ô sẽ có màu trắng, nếu không sẽ có màu đen. Để kiểm tra này, chúng tôi sử dụng toán tử còn lại % trong thuật toán. Vì chúng ta không làm việc với đồ họa mà bằng các ký hiệu, nên chúng ta sẽ biểu thị ô màu trắng bằng chữ cái W(màu trắng) và ô màu đen bằng chữ cái B(màu đen).
//set the chessboard as a two-dimensional array
String [][] chessBoard = new String[8][8];
        for (int i = 0; i< chessBoard.length; i++) {
            for (int j = 0; j < chessBoard[0].length; j++) {
                if ((i + j) % 2 == 0) chessBoard[i][j] = "W";
                else chessBoard[i][j] = "B";
            }
        }
Kết quả đầu ra của chương trình như sau: WBWBWBWBBWBWBWBWWBWBW BWBBWBWBWBWWBWBWBWBBW BWBWBWWBWBWBWBBWBWBWB W Mọi thứ giống như trên bàn cờ thật, bạn có thể kiểm tra. Mảng đa chiều - 4Bây giờ chúng ta hãy viết một phương pháp đánh số chính xác các ô không phải bằng ngôn ngữ mảng mà bằng ngôn ngữ "cờ vua". Ô phía dưới bên trái trên bảng được gọi là A1, trong khi trong mảng của chúng ta nó là chessBoard[7][0]. Chúng ta hãy liên kết từng cặp chỉ số của mảng hai chiều với tương đương “cờ vua” của chúng. Để làm điều này, chúng tôi sử dụng hai dòng - " abcdefgh" và " 87654321" (theo thứ tự ngược lại - để đơn giản, sao cho bàn cờ 8 tương ứng với cột số 0).
public static String chessBoardCoord(int a, int b) {
            String letters = "abcdefgh";
            String numbers = "87654321";
            if ((a > 7)|| (b>7)) return null; //if the number is outside the board, return the default value - null
            else return (Character.toString(letters.charAt(a)) + numbers.charAt(b)); /*charAt - a method with which we extract from the string the element under the passed number, here - under the numbers a and b. Character.toString - a method that converts the received character into a string */
        }
Bây giờ, hãy hiển thị trong mỗi ô không chỉ màu sắc mà còn cả số của nó bằng cách sử dụng phương thứcchessBoardCoord
String [][] chessBoard = new String[8][8];
        for (int i = 0; i < chessBoard.length; i++) {
            for (int j = 0; j < chessBoard[0].length; j++) {
                if ((i + j) % 2 == 0) chessBoard[i][j] = "W" + chessBoardCoord(j,i);
                else chessBoard[i][j] = "B"+ chessBoardCoord(j,i);
            }
        }

            for (int i = 0; i < chessBoard.length; i++) {
                for (int j = 0; j < chessBoard[0].length; j++) {
                    System.out.print(" " + chessBoard[i][j] + " ");
                }
                System.out.println();
            }
Đầu ra chương trình: Wa8 Bb8 Wc8 Bd8 We8 Bf8 Wg8 Bh8 Ba7 Wb7 Bc7 Wd7 Be7 Wf7 Bg7 Wh7 Wa6 Bb6 Wc6 Bd6 We6 Bf6 Wg6 Bh6 Ba5 Wb5 Bc5 Wd5 Be5 Wf5 Bg5 Wh5 Wa4 Bb4 Wc4 Bd4 We4 Bf4 Wg4 Bh4 Ba3 Wb3 Bc3 Wd 3 Be3 Wf3 Bg3 Wh3 Wa2 Bb2 Wc2 Bd2 We2 Bf2 Wg2 Bh2 Ba1 Wb1 Bc1 Wd1 Be1 Wf1 Bg1 Wh1 Ở đâu We2có nghĩa là hình vuông màu trắng được đánh số e2.

Ví dụ về sử dụng mảng hai chiều: phép nhân ma trận

Chú ý!Ví dụ này đòi hỏi kiến ​​thức cơ bản về ma trận. Ở đây sẽ nói rất ít về chúng, và thông tin này dành cho những người đã nghiên cứu nhưng đã quên phần nào về số học ma trận. Tuy nhiên, kiến ​​thức này có thể được thu thập từ các nguồn mở, đặc biệt là từ một bài viết trên Wikipedia . Đây là một ví dụ hay về việc sử dụng mảng hai chiều, nhưng chúng ta có thể tiếp tục mà không cần đến nó. Vì vậy, nếu bây giờ nó có vẻ khó hiểu đối với bạn từ quan điểm toán học và bạn không thực sự muốn tìm hiểu sâu về nó, vui lòng bỏ qua ví dụ này. Nếu bạn đã học đại số tuyến tính cơ bản, bạn có thể đã học về ma trận hình chữ nhật như ma trận hình chữ nhật. Mảng đa chiều - 5Trong đó a11, a12... aNN là một số số. Trong hình, ma trận thậm chí không phải là hình chữ nhật mà là hình vuông (số hàng bằng số cột, nhưng điều này không phải lúc nào cũng đúng). Trong đời thực, những ma trận như vậy hiếm khi gặp nhưng trong lập trình và khoa học máy tính thì chúng lại rất phổ biến. Đặc biệt, chúng được sử dụng trong đồ họa máy tính và công cụ trò chơi. Ví dụ: việc xoay một vật thể trên màn hình theo bất kỳ góc nào có thể được lập trình bằng ma trận xoay. Trong không gian hai chiều, ma trận quay trông như thế này: Mảng đa chiều - 6Trong đó theta là góc mà vật cần quay. Các ma trận có kích thước bằng nhau có thể được cộng với nhau và phép cộng xảy ra theo từng phần tử (chúng ta thêm các phần tử có cùng chỉ số). Nhưng phép nhân ma trận ít quen thuộc hơn. Do đó, các ma trận có thể được nhân và chỉ có thể thu được ma trận kết quả nếu số cột của ma trận thứ nhất trùng với số hàng của ma trận thứ hai. Ma trận kết quả sẽ có cùng số hàng với ma trận đầu tiên và cùng số cột với ma trận thứ hai. Phép nhân được thực hiện như sau. Chúng ta hãy có một ma trận a[l][m]b[m][n]. Kết quả của phép nhân của chúng, chúng ta sẽ thu được một ma trận c[l][n]. Để thu được một phần tử của c[0][0]ma trận tích, bạn cần a[0][0]nhân phần tử 0 của hàng 0 của ma trận thứ nhất với phần tử 0 của ma trận thứ hai, sau đó nhân phần tử đầu tiên của hàng đầu tiên của ma trận thứ nhất với phần tử đầu tiên của cột đầu tiên của ma trận thứ hai, v.v., sau đó tất cả các sản phẩm thu được sẽ được thêm vào.

a[0][0]*b[0][0] + a[0][1]*b[1][0] + … + a[0][m-1]*b[m-1][0]
Để lấy phần tử thứ hai của hàng đầu tiên của ma trận kết quả, chúng ta thực hiện quy trình tương tự với hàng thứ hai

a[1][0]*b[0][0] + a[1][1]*b[0][1] + … + a[0][m-1]*b[m-1][0]
Và cứ như vậy cho đến hết dòng. Sau đó, chúng ta chuyển sang dòng tiếp theo và lặp lại quy trình cho đến khi hết dòng. Tức là chúng ta nhân các hàng của ma trận thứ nhất với các cột của ma trận thứ hai. Dưới đây là mã để nhân ma trận. Bạn có thể bổ sung bằng cách kiểm tra việc tuân thủ điều kiện nêu trên về số lượng hàng và cột.
//declaring two matrices
int [][] twoDimArray1 = {{1,0,0,0},{0,1,0,0},{0,0,0,0}};
int[][] twoDimArray2 = {{1,2,3},{1,1,1},{0,0,0},{2,1,0}};

//matrix multiplication process
int[][]twoDimArray3 = new int [twoDimArray1.length][twoDimArray2[0].length];
        for (int i=0; i<twoDimArray3[0].length; i++)
            for (int j=0; j<twoDimArray3.length; j++)
                for (int k=0; k<twoDimArray1[0].length; k++)
                              twoDimArray3[i][j] = twoDimArray3[i][j] + twoDimArray1[i][k] * twoDimArray2[k][j];

//output on display
        for (int i = 0; i < twoDimArray3.length; i++) {
            for (int j = 0; j < twoDimArray3[0].length; j++) {
                System.out.print(" " + twoDimArray3[i][j] + " ");
            }
            System.out.println();
        }
Chương trình đưa ra kết quả như sau: 1 2 3 1 1 1 0 0 0

Mảng hai chiều không phải hình chữ nhật

Vì mảng hai chiều là mảng của các mảng trong Java nên mỗi mảng bên trong có thể có độ dài khác nhau. Khi tạo một mảng, chúng ta chỉ có thể chỉ định số hàng chứ không thể xác định số cột (thực chất là độ dài của các hàng giống nhau). Hãy xem một ví dụ.
//declaring and creating an array, specifying only the number of rows
int [][] twoDimArray = new int[5][];

//initialize the array, filling it with arrays of different lengths
        twoDimArray[0] = new int[]{1, 2, 3, 4, 5};
        twoDimArray[1] = new int[]{1,2,3,4};
        twoDimArray[2] = new int[]{1,2,3};
        twoDimArray[3] = new int[]{1,2};
        twoDimArray[4] = new int[]{1};
//display the resulting non-rectangular two-dimensional array on the screen
        for (int i = 0; i < twoDimArray.length; i++) {
            for (int j = 0; j < twoDimArray[i].length; j++) {
                System.out.print(" " + twoDimArray[i][j] + " ");
            }
            System.out.println();
        }
Đầu ra chương trình: 1 2 3 4 5 1 2 3 4 1 2 3 1 2 1 Do đó, dòng thứ 0 của mảng của chúng ta chứa mảng {1,2,3,4,5}và dòng thứ tư chứa mảng {1}.

Mảng ba chiều trong Java

Theo lẽ thông thường và logic của ngôn ngữ Java, mảng ba chiều có thể được gọi là “mảng của các mảng” hoặc “mảng có mỗi phần tử là mảng hai chiều”. Hơn nữa, các mảng hai chiều này có thể khác nhau. Ví dụ:
// create a three-dimensional array consisting of two two-dimensional arrays
int[][][] threeDimArr = new int[2][][];
//create the first 2D array of a 5x2 3D array
        threeDimArr[0] = new int[5][2];
//create a second 2D array of a 1x1 3D array
        threeDimArr[1] = new int[1][1];
Nhưng thường xuyên hơn trong thực tế có các mảng ba chiều trong đó cả ba đại lượng được xác định cùng một lúc, tương tự như mảng hai chiều hình chữ nhật. Mảng đa chiều - 7Như chúng tôi đã đề cập, mảng ba chiều trở lên rất hiếm khi được sử dụng. Tuy nhiên, bạn có thể lập trình điều gì đó thú vị với mảng 3D. Ví dụ như bãi đỗ xe nhiều tầng. Mỗi tầng có thể được coi là một mảng hai chiều và chỗ đỗ xe có thể được coi là một phần tử cụ thể của mảng ba chiều. Một phần tử của mảng như vậy có thể được biểu diễn bằng một kiểu booleancó giá trị sai nếu không gian trống và đúng nếu không gian bị chiếm.
//set a boolean three-dimensional array. This car park has 3 floors, each of which can accommodate 2x5 = 10 cars. By default, all cells are empty (false)
boolean[][][] parkingLot = new boolean[3][2][5];
//two cars arrived and parked on the ground floor in cell [1][0] and [1][3]
        parkingLot[0][1][0] = true;
        parkingLot[0][1][3] = true;

//Output the array to the console
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 2; j++) {
                for (int k = 0; k < 5; k++) {
                    System.out.print("arr[" + i + "][" + j + "][" + k + "] = " + parkingLot[i][j][k] + "\t");

                }
                System.out.println();
            }
        }

Mảng đa chiều trong công việc thực tế của lập trình viên Java

Trong thực tế, hầu hết các nhà phát triển Java không thường xuyên gặp phải mảng đa chiều. Tuy nhiên, có một số nhiệm vụ mà cấu trúc dữ liệu này rất phù hợp.

  1. Để kiểm tra và thiết lập ma trận dưới dạng hằng số để kiểm tra một thuật toán cụ thể.
  2. Đôi khi mảng đa chiều được sử dụng cho mạng lưới thần kinh.
  3. Mảng đa chiều thích hợp cho người lưu trữ.
  4. Làm việc với hình ảnh.

Các bài toán thú vị về mảng hai chiều và ba chiều

Bạn đã biết đủ về mảng nhiều chiều trong Java và nếu cảm thấy tự tin, bạn có thể thử giải một số bài toán dưới đây. Chúng không dễ dàng, nhưng thú vị. TIC Tac Toe. Thiết lập trường 3x3, tạo hai người chơi thay phiên nhau. Ban đầu, trường trống và ở mỗi ô trống, người chơi đầu tiên có thể đặt một cây thánh giá và người chơi thứ hai là số 0. Người chiến thắng là người đầu tiên thu thập được ba chữ thập hoặc ba số 0 xếp thành một hàng, một cột hoặc chéo. Kiến Langton . Có một trường nhất định, được chia thành các ô (mảng hai chiều), được sơn màu đen hoặc trắng (có thể được đặt bằng hàm ngẫu nhiên). Một con kiến ​​xuất hiện ngẫu nhiên ở một trong các ô và ở mỗi bước nó có thể di chuyển theo một trong bốn hướng đến ô liền kề, theo chiều ngang hoặc chiều dọc. Quy luật di chuyển của kiến:
  • Trên hình vuông màu đen, con kiến ​​phải quay sang trái 90°, đổi màu ô của nó thành màu trắng, sau đó bước tới hình vuông tiếp theo.
  • Trên hình vuông màu trắng, con kiến ​​quay sang phải 90° và đổi màu ô của nó thành màu đen, sau đó bước tới hình vuông tiếp theo.
Viết phương thức tính số bước lặp ntại vị trí ban đầu của con kiến. Trường này có thể được điền ngẫu nhiên bằng số 0 và số 1 (hoặc được biểu thị bằng các chữ cái WB, như chúng ta đã làm trong ví dụ về bàn cờ). Chúng ta cũng cần thêm hai tham số - vị trí ngang và dọc của con kiến, cũng như hướng của nó ở bước này (bắc, nam, tây, đông), trong khi theo mặc định con kiến ​​nhìn về phía bắc. Bạn có thể thử mô hình khối Rubik bằng cách sử dụng mảng ba chiều. Một khối Rubik tiêu chuẩn có 6 mặt và mỗi mặt là một mảng ba chiều gồm các hình vuông màu Color[][][] rubik = new Color[6][3][3]. Tuy nhiên, việc thực hiện khối Rubik không phải là một việc dễ dàng.

Tài liệu hữu ích về mảng

Nhiều bài viết trên JavaRush được dành cho mảng (chủ yếu là mảng một chiều, vì chúng thường được sử dụng nhiều hơn trong thực tế). Hãy chú ý đến họ.
  1. Mảng trong Java - về mảng cho người mới bắt đầu kèm ví dụ
  2. Đôi điều về mảng - Bài viết chi tiết về mảng
  3. Lớp Arrays và công dụng của nó - bài viết mô tả một số phương thức của lớpArray
  4. Mảng là bài giảng JavaRush đầu tiên dành riêng cho mảng.
  5. Trả về một mảng có độ dài bằng 0, không phải null - Tác giả Lập trình hiệu quả Joshua Bloch nói về cách trả về các mảng trống tốt hơn
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION