Trang chủ Liên hệ

Bài 23 C# cơ bản - Mảng nhiều chiều trong lập trình C# cơ bản

CÔNG TY TNHH THIẾT BỊ ĐO LƯỜNG VÀ ĐIỀU KHIỂN 04/03/2023

Nội dung

Để đọc hiểu bài này tốt nhất các bạn nên có kiến thức cơ bản về các phần:

Trong bài học này, chúng ta sẽ cùng tìm hiểu các vấn đề:

Mảng nhiều chiều trong C#

Ngoài mảng 1 chiều và mảng 2 chiều ra thì C# còn hỗ trợ chúng ta khai báo và sử dụng mảng 3 chiều, 4 chiều thậm chí là n chiều tuỳ vào từng yêu cầu của bài toán.

Trong phạm vi bài viết này mình chỉ trình bày về mảng 3 chiều, còn về mảng 4 chiều trở đi thì các bạn có thể tự nghiên cứu thêm.

Về khái niệm của mảng cũng như các đặc trưng cơ bản của mảng mình đã trình bày trong bài MẢNG 1 CHIỀU TRONG C# rồi nên ở đây mình sẽ không nhắc lại mà đi trực tiếp vào vấn đề luôn.

Mảng 3 chiều trong C#

Nếu như mảng 2 chiều được hình dung như là một ma trận MxN thì mảng 3 chiều được hình dung như một hình hộp chữ nhật có kích thước MxNxP.

Cú pháp:

<kiểu dữ liệu> [ , , ] <tên mảng>;

Trong đó:

Để sử dụng được mảng ta phải khởi tạo giá trị hoặc cấp phát vùng nhớ cho mảng.

Cấp phát vùng nhớ

Được thực hiện tương tự như mảng 2 chiều nhưng cần chỉ ra 3 chỉ số cho mảng.

Ví dụ:

            /*
             * Khai báo mảng 3 chiều kiểu string và có tên là mctt.
             * Sau đó thực hiện cấp phát vùng nhớ với 3 chỉ số lần lượt là 2, 2, 3.
             */

             string[ , , ] mctt = new string[2, 2, 3];

Sau khi mảng được cấp phát vùng nhớ thì các phần tử trong mảng sẽ mang giá trị mặc định:

Sau khi mảng được cấp phát vùng nhớ thì các phần tử trong mảng sẽ mang giá trị mặc định:

Chúng ta có thể khởi tạo giá trị khác mà chúng ta mong muốn ngay khi cấp phát vùng nhớ  bằng cú pháp sau:

Khởi tạo giá trị

Việc khởi tạo giá trị hoàn toàn tương tự như phần trên mình đã trình bày.

Cú pháp:

Ví dụ:

            int[,,] Mang3Chieu = new int[,,]
            {
                {
                    {1, 2, 3},
                    {4, 5, 6}
                },
                {
                    {7, 8, 9},
                    {10, 11, 12}
                }
            };

Tóm lại, cũng như mảng 2 chiều, mảng 3 chiều cũng có 3 cách khai báo và khởi tạo sau:

string[ , , ] Array = new string[2, 2, 3];

Sử dụng mảng 3 chiều:

Tương tự như mảng 2 chiều, kiểu mảng 3 chiều cũng có thể dùng làm:

 Các phần tử của mảng được truy xuất thông qua 3 chỉ số ngăn cách nhau bởi dấu phẩy và nằm trong cặp dấu [].

// Khai báo, cấp phát và khởi tạo mảng 3 chiều kiểu int và tên là Mang3Chieu
int[,,] Mang3Chieu = new int[,,]
            {
                {
                    {1, 2, 3},
                    {4, 5, 6}
                },
                {
                    {7, 8, 9},
                    {10, 11, 12}
                }
            };
/*
 * Truy xuất đến phần tử có các chỉ số lần lượt là 1 1 2
*/        
            Console.WriteLine(Mang3Chieu[1, 1, 2]);

Tương tự như mảng 2 chiều, mảng 3 chiều cũng có một số thuộc tính và phương thức đặc trưng như mảng 2 chiều:

Tên thuộc tính hoặc phương thức

Ý nghĩa

Length

Thuộc tính trả về số nguyên kiểu int là số phần tử tối đa của mảng (số phần tử của mảng 3 chiều là tích 3 chỉ số của mảng)

LongLength

Tương tự như thuộc tính Length nhưng trả về số nguyên kiểu long

GetLength(<số chiều>)

Trả về số nguyên kiểu int là số phần tử trong chiều đã xác định. Lưu ý chiều của mảng là các số nguyên và được đánh số từ 0. Đối với mảng 3 chiều thì GetLength(0) là độ dài chiều đầu tiên và GetLength(1) là độ dài chiều thứ 2 và GetLength(2) là độ dài chiều thứ 3.

GetLongLength(<số chiều>)

Tương tự GetLength nhưng trả về số nguyên kiểu long

Rank

Thuộc tính trả về số nguyên int là số chiều của mảng

Clone()

Thực hiện copy giá trị của mảng ra một vùng nhớ mới (phép gán thông thường thì 2 đối tượng sẽ dùng chung vùng nhớ rất nguy hiểm vì đối tượng này thay đổi dẫn đến đối tượng kia cũng thay đổi)

Còn rất nhiều thuộc tính và phương thức khác, mình chỉ giới thiệu một số cái hay dùng còn lại các bạn có thể tự khám phá.

Cách duyệt mảng 3 chiều:

int[, ,] IntArray = new int[3, 9, 10];

            /*
             * Sử dụng 3 vòng for lồng vào nhau để duyệt mảng 3 chiều
             * Vòng lặp đầu tiên là vòng lặp duyệt các phần tử của chiều đầu tiên.
             * Vòng lặp thứ 2 là vòng lặp duyệt các phần tử của chiều thứ 2.
             * Vòng lặp thứ 3 là vòng lặp duyệt các phần tử của chiều thứ 3.
             */

            for (int i = 0; i < IntArray.GetLength(0); i++)
            {
                for (int j = 0; j < IntArray.GetLength(1); j++)
                {
                    for (int k = 0; k < IntArray.GetLength(2); k++)
                    {

                        /*
                        * Với cách duyệt này thì IntArray[i, j, k] sẽ là phần tử hiện tại mình đang xét
                        * Code xử lý sẽ viết ở đây
                        */  

                    }
                }
            }

Cách duyệt này sẽ duyệt tuần tự các chiều trong mảng 3 chiều, ở mỗi chiều sẽ duyệt từ đầu đến cuối. Bạn hoàn toàn có thể duyệt theo ý mình bằng cách thay đổi giá trị trong vòng lặp.

Vì mảng 3 chiều cũng ít được sử dụng nên mình chỉ giới thiệu qua thôi chứ không đi quá chi tiết. Với kiến thức cơ bản mình đã cung cấp các bạn hoàn toàn có thể tự tìm hiểu thêm khi cần thiết.

Mảng jagged trong C#

Mảng jagged (hay còn gọi là mảng lởm chởm) là một mảng của các mảng. Nghe có vẻ giống mảng 2 chiều đã học nhưng thực ra là rất khác.

Đặc điểm của mảng jagged cũng là điểm khác biệt giữa mảng này với mảng 2 chiều:

Ưu điểm lớn nhất của mảng jagged là tiết kiệm bộ nhớ. Bởi vì khi mình cần xài bao nhiêu thì mình cấp phát bấy nhiêu nên sẽ không bị thừa một ô nhớ nào.

Khai báo mảng jagged

Cú pháp:

<kiểu dữ liệu> [ ][ ] <tên mảng>;

Trong đó:

Ví dụ

int [][] JaggedArray;

Cấp phát vùng nhớ

Không giống như mảng 2 chiều, mảng jagged không cho phép cấp phát cùng lúc số dòng và số cột mà phải cấp phát số dòng trước sau đó ứng với mỗi dòng ta cấp phát số cột theo ý muốn.

Để hiểu hơn về cách cấp phát vùng nhớ cho mảng jagged thì ta xem qua ví dụ sau:

            int [][] JaggedArray = new int[3][];

            JaggedArray[0] = new int[3];

            JaggedArray[1] = new int[9];

            JaggedArray[2] = new int[10];

Từ ví dụ ta có thể thấy:

Khởi tạo giá trị

Cách khởi tạo giá trị của mảng jagged cũng có chút khác so với mảng 2 chiều. Ta xem qua ví dụ sau:

int[][] JArray =

{

    new int[] {1, 2, 3},

    new int[] {3, 4, 5, 6, 7, 8, 9}

};

Từ ví dụ có thể thấy là:

Sử dụng mảng jagged

Khi sử dụng mảng jagged các bạn cần lưu ý:

Cách duyệt mảng jagged

Các bạn hoàn toàn có thể duyệt mảng jagged bằng 2 vòng lặp for lồng vào nhau như mảng 2 chiều. Nhưng chúng ta cần linh hoạt hơn ở vòng lặp thứ 2 để tránh chương trình bị lỗi.

Cùng xét qua ví dụ sau:

/*

             * Khai báo 1 mảng jagged tên JArray và có 2 phần tử tương ứng với 2 mảng con.

             * Mảng con thứ nhất là mảng 1 chiều có 3 phần tử.

             * Mảng con thứ hai là mảng 1 chiều có 7 phần tử.

             */

            int[][] JArray =

            {

                new int[] {1, 2, 3},

                new int[] {3, 4, 5, 6, 7, 8, 9}

            };

            /*

             * Sử dụng 2 vòng lặp lồng vào nhau để duyệt mảng jagged này.

             * Vòng lặp đầu tiên là vòng lặp duyệt số phần tử của mảng 1 chiều.

             * Vì mỗi phần tử là 1 mảng 1 chiều nên vòng lặp thứ 2 là để duyệt mảng 1 chiều tại vị trí tương ứng.

             * Do các mảng 1 chiều có kích thước khác nhau nên ta dùng thuộc tính Length để xác định kích thước.

             */

            for (int i = 0; i < JArray.Length; i++)

            {

                for (int j = 0; j < JArray[i].Length; j++)

                {

                    /*

                     * JArray[i][j] là cách truy xuất đến mảng 1 chiều thứ i và phần tử thứ j trong mảng đó.

                     */

                    Console.Write("\t" + JArray[i][j]);

                }

                Console.WriteLine();

            }

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 (khái niệm kế thừa sẽ được trình bày trong bài TÍNH KẾ THỪA TRONG C#).

Một số thuộc tính trong lớp Array:

Tên thuộc tính

Ý nghĩa

Length

Thuộc tính trả về số nguyên kiểu int là số phần tử tối đa của mảng.

LongLength

Tương tự như thuộc tính Length nhưng trả về số nguyên kiểu long

Rank

Thuộc tính trả về số nguyên int là số chiều của mảng

Một số phương thức trong lớp Array:

Tên phương thức

Ý nghĩa

Clear()

Thiết lập lại giá trị mặc định co tất cả các phần tử trong mảng.

GetLength(<số chiều>)

Trả về số nguyên kiểu int là số phần tử trong chiều đã xác định. Lưu ý chiều của mảng là các số nguyên và được đánh số từ 0.

GetLongLength(<số chiều>)

Tương tự GetLength nhưng trả về số nguyên kiểu long

GetValue(<vị trí>)

Trả về giá trị 1 phần tử của mảng tại vị trí truyền vào. Nếu là mảng nhiều chiều thì có thể truyền vào danh sách các chỉ số.

Reverse(<tên mảng>)

Đảo ngược các giá trị của mảng 1 chiều.

Sort(<tên mảng>)

Sắp xếp các phần tử của mảng 1 chiều.

IndexOf(<tên mảng>, <phần tử cần tìm>)

Tìm kiếm 1 phần tử có tồn tại trong mảng hay không. Nếu có thì trả về vị trí xuất hiện đầu tiên trong mảng ngược lại sẽ trả về 0.

Đây chỉ là một số thuộc tính và phương thức tiêu biểu. Ngoài ra còn nhiều phương thức, thuộc tính khác các bạn có thể tự khám phá.

Lưu ý là các phương thức SortReverseIndexOf được gọi thông qua tên lớp. Tức là muốn sử dụng các phương thức trên ta sẽ dùng cú pháp:

Nhờ sự hỗ trợ của các phương thức trên mà ta có thể dễ dàng thao tác với dữ liệu mảng như sắp xếp, đảo ngược, . . . mà không cần phải viết chi tiết ra giải thuật như thế nào.

Sau đây là một vài ví dụ ứng dụng lớp Array:

Sắp xếp dãy số tăng, giảm dần

Code: 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Bai_23_01
{
    class Program
    {
        static void Main(string[] args)
        {
            //Khoi toa mang 1 chieu MangSL
            int[] MangSL = {5,2,1,3};

            //Thuc hien sap xep tang dan
            Array.Sort(MangSL);
            Console.WriteLine("Mang sap xep tang dan");
            for (int i=0;i<MangSL.Length;i++)
            {
                Console.Write("\t" + MangSL[i]);
            }
            Console.WriteLine();

            //Dao nguoc, sap sep mang giam dan
            Array.Reverse(MangSL);
            Console.WriteLine("Mang sap xep giam dan");
            for (int i=0;i<MangSL.Length;i++)
            {
                Console.Write("\t" + MangSL[i]);
            }
            Console.ReadLine();
        }
    }
} 

 

Ngoài ra lớp Array cũng hỗ trợ bạn khai báo sử dụng mảng nhưng thường thì ít ai sử dụng vì nó dài dòng và không tường minh.

Kết luận

Nội dung bài này giúp các bạn nắm được:

Bài sau chúng ta sẽ tìm hiểu về CẤU TRÚC LẶP FOREACH TRONG C#.

Bài viết liên quan