Mảng đa chiều, mảng của mảng trong C#
Nguyễn Dương 07-06-2024Trong 2 bài viết trước, chúng ta đã cùng tìm hiều về mảng 1 chiều, mảng 2 chiều trong C#. Nhưng thực chất, C# còn hỗ trợ chúng ta mảng 3 chiều, 4 chiều, 5 chiều, 6 chiều cho đến n chiều tùy vào yêu cầu của bài toán. Ngoài ra còn có mảng của mảng, đó là 1 mảng mà mỗi phần tử là một mảng khác. Trong bài viết này, chúng ta cùng tìm hiều về mảng 3 chiều và mảng của mảng nhé.
1. MẢNG 3 CHIỀU
Trong bài viết trước, mình đã từng nói, mảng 2 chiều giống như một cái bảng gồm m hàng và n cột. Đối với mảng 3 chiều thì các bạn hình dung nó giống như một cái hình hộp chữ nhật vậy, gồm chiều dài, chiều rộng và chiều cao.
Nhìn vào hình trên, nếu coi mặt ngoài của hình hộp là 1 mảng 2 chiều gồm m hàng và n cột thì hình hộp đó sẽ là một mảng 3 chiều, gồm x mảng 2 chiều.
- Cách khai báo như sau:
<kiểu dữ liệu> [,,] <tên mảng>;
Cách khai báo tương tự mảng 1 chiều và 2 chiều, chỉ thêm dấu phẩy ở trong ngoặc vuông [ ]
Đối với mảng n chiều thì thêm n - 1 dấu phẩy.
- Cấp phát vùng nhớ
int[,,] ArrayC = new int[2, 3, 5];
Trong ví dụ này thì chúng ta có thể hình dung là mảng ArrayC có 2 mảng 2 chiều, mỗi mảng gồm 3 hàng và 5 cột.
- Khởi tạo giá trị
int[,,] ArrayC = new int[,,] { { {1, 2, 69, 5, 8}, {4, 5, 6, 11, 15}, {9, 5, 6, 21, 25} }, { {7, 8, 9, 1, 5}, {10, 11, 12, 55, 56}, {20, 11, 22, 15, 16} } };
- Cách sử dụng mảng 3 chiều tương tự mảng 1 chiều và 2 chiều.
Ví dụ: Truy xuất phần tử [0, 0, 2]
int[,,] ArrayC = new int[,,]
{
{
{1, 2, 69, 5, 8},
{4, 5, 6, 11, 15},
{9, 5, 6, 21, 25}
},
{
{7, 8, 9, 1, 5},
{10, 11, 12, 55, 56},
{20, 11, 22, 15, 16}
}
};
Console.WriteLine(ArrayC[0,0,2]);
Kết quả sẽ là 69
- Các thuộc tính và phương thức tương tự mảng 2 chiều.
- Cách duyệt mảng 3 chiều tương tự mảng 2 chiều, ở đây vì là 3 chiều nên ta cần 3 vòng lặp.
Ví dụ:
Ví dụ:
int[,,] ArrayC = new int[,,]
{
{
{1, 2, 69, 5, 8},
{4, 5, 6, 11, 15},
{9, 5, 6, 21, 25}
},
{
{7, 8, 9, 1, 5},
{10, 11, 12, 55, 56},
{20, 11, 22, 15, 16}
}
};
for (int i =0; i < ArrayC.GetLength(0); i++)
{
for (int j = 0; j < ArrayC.GetLength(1); j++)
{
for (int k = 0; k < ArrayC.GetLength(2); k++)
{
Console.WriteLine("Gia tri phan tu [{0},{1},{2}] là: {3}", i, j, k, ArrayC[i,j,k]);
}
}
}
2. MẢNG CỦA MẢNG
Mảng jagged là một mảng của các mảng. Nó là một mảng mà trong đó, mỗi phần tử có thể là một mảng khác.
Đặc điểm:
- Các ô nhớ được cấp phát có thể không nằm liền kề nhau
- Bản chất vẫn là mảng 1 chiều nhưng các phần tử có thể chứa 1 mảng khác
Đặc điểm:
- Các ô nhớ được cấp phát có thể không nằm liền kề nhau
- Bản chất vẫn là mảng 1 chiều nhưng các phần tử có thể chứa 1 mảng khác
- Số phần tử của chiều thứ 2 có thể khác nhau
Ưu điểm lớn nhất của mảng jagged là tiết kiệm bộ nhớ. Bởi vì cần dùng bao nhiêu thì cấp phát bấy nhiêu nên sẽ không bị thừa một ô nhớ nào.
Cách khai báo:
<kiểu dữ liệu> [][] <tên mảng>;
Cấp phát vùng nhớ:
Ví dụ:
int [][] ArrayC = new int[3][];
ArrayC[0] = new int[6];
ArrayC[1] = new int[9];
ArrayC[2] = new int[6];
Vì mảng jagged là mảng 1 chiều nên đầu tiên ta cần cấp phát số phần tử cho mảng 1 chiều. Sau đó ứng với mỗi phần tử của mảng 1 chiều đó ta cấp phát 1 mảng 1 chiều nữa.
Chính vì điểm này nên ta có thể linh động chọn số phần tử phù hợp cho từng dòng.
Khởi tạo giá trị:
int[][] ArrayC =
{
new int[] {1, 2, 3},
new int[] {4, 5, 6, 7, 8, 9}
};
Nhìn vào ví dụ này bạn sẽ thấy, không thể khởi tạo trực tiếp giá trị từng vị trí như mảng 2 chiều được. Ứng với mỗi dòng ta phải cấp phát vùng nhớ rồi mới khởi tạo giá trị được.
Lưu ý khi sử dụng mảng jagged
- Vì đây là mảng trong mảng nên cách truy xuất có chút khác biệt. Đó là sử dụng <tên mảng>[i] [j] thay vì <tên mảng>[i, j]
- i, j không được xem là chỉ số dòng và chỉ số cột nữa mà i được hiểu là chỉ số chỉ vị trí phần tử trong mảng mẹ, còn j là chỉ số phần tử của mảng 1 chiều nằm tại vị trí i trên
- Chỉ có thể sử dụng phương thức GetLength(0) chứ không thể sử dụng GetLength(1) vì mảng jagged bản chất vẫn là mảng 1 chiều
- Nếu ta truy xuất <tên mảng>[i] thì có thể xem đây là 1 mảng 1 chiều và có thể thao tác như một mảng 1 chiều bình thường
Cách duyệt mảng
int[][] ArrayC=
{
new int[] {1, 2, 3, 4, 5 },
new int[] {69, 96, 696, 969, 10}
};
for (int i = 0; i < ArrayC.Length; i++)
{
for (int j = 0; j < ArrayC[i].Length; j++)
{
Console.WriteLine("Gia tri phan tu [{0}][{1}] là: {2}", i, j, ArrayC[i][j]);
}
}
Lưu ý là chúng ta nên dùng Length thay cho GetLength. Vòng lặp đầu thì lấy số phần tử của mảng, vì bản chất đây là mảng 1 chiều, vòng lặp 2 thì lấy độ dài của phần tử thứ i.
3. LỚP ARRAY TRONG C#
Lớp Array trong C# là lớp cơ sở cho mọi mảng, một mảng bất kỳ đều được kế thừa từ lớp này.Một số thuộc tính phổ biến của lớp Array trong C#.
- Length: Trả về kết quả là tổng số phần tử của mảng, kiểu int
- LongLength: Tương tự Length nhưng trả về kiểu long
- Rank: Lấy số chiều của mảng
- Clear: Thiết lập lại giá trị mặc định của tất cả các phần tử trong mảng
- GetLength(số chiều): Trả về số phần tử trong chiều xác định (kiểu int)
- GetLongLength(số chiều): Tác dụng tương tự GetLength, trả về kiểu long
- GetValue(<vị trí>): Trả về giá trị của một phần tử theo vị trí truyền vào
- Reverse(<tên mảng>): Đảo ngược dãy phần tử trong mảng một chiều
- Sort(<tên mảng>): Sắp xếp các phần tử trong mảng một chiều
- IndexOf(<tên mảng>, <phần tử cần tìm>): Tìm kiếm 1 phần tử có xuất hiện trong mảng hay không. Nếu có thì trả về vị trí đầu tiên trong mảng, nếu không trả về 0.
Ví dụ:
int[] ArrayC = { 69, 96, 89, 98, 101 }; Console.WriteLine("Mảng ArrayC gồm các phần tử: "); for (int i = 0; i < ArrayC.Length; i++) { Console.Write("{0,5}", ArrayC[i]); } Console.WriteLine(); Array.Sort(ArrayC); Console.WriteLine("Mảng sau khi đã sắp xếp:"); for (int i = 0; i < ArrayC.Length; i++) { Console.Write("{0,5}", ArrayC[i]); } Console.WriteLine(); Array.Reverse(ArrayC); Console.WriteLine("Mảng sau khi đã đảo chiều:"); for (int i = 0; i < ArrayC.Length; i++) { Console.Write("{0,5}", ArrayC[i]); }
Kết quả:
Bài viết liên quan
Hàm đệ quy trong C#
enum trong C#
Struct trong C#
Lớp String trong C#
Vòng lặp foreach trong C#
Mảng đa chiều, mảng của mảng trong C#