Chuyển đến nội dung chính

Ép Kiểu Trong C++

Ép kiểu trong C++ là việc gán giá trị của một biến có kiểu dữ liệu này tới biến khác có kiểu dữ liệu khác. Trong bài viết ngày hôm nay, chúng ta sẽ tìm hiểu kĩ hơn về ép kiểu trong C++ qua bai viết dưới đây nhé.

I. Ép Kiểu Trong C++ Là Gì

Toán tử ép kiểu (một cast) trong C++ là 1 toán tử đặc biệt mà làm một kiểu dữ liệu này biến đổi thành kiểu dữ liệu khác. Toán tử ép kiểu là một toán tử 1 ngôi và có cùng độ ưu tiên như bất kỳ toán tử một ngôi nào khác trong C++.

Cú pháp được dùng thường xuyên của toán tử ép kiểu trong C++ là:

(kieu_du_lieu) bieu_thuc

Ở đây, kieu_du_lieu là kiểu dữ liệu bạn muốn. Dưới đây là một số toán tử ép kiểu được hỗ trợ bởi C++:

const_cast<kieu_du_lieu> (bieu_thuc): Toán tử const_cast được sử dụng để ghi đè const và/hoặc volatile. Kiểu dữ liệu bạn muốn buộc phải giống như kiểu dữ liệu nguồn ngoại trừ sự sửa đổi của những thuộc tính const hoặc volatile trong một cast. Dạng ép kiểu này thao tác thuộc tính const của đối tượng đã truyền: hoặc được thiết lập hoặc gỡ bỏ.

dynamic_cast<kieu_du_lieu> (bieu_thuc): Toán tử dynamic_cast trong C++ thực hiện một ép kiểu tại runtime mà thẩm tra tính hợp lệ của cast. Nếu cast không thể được tạo ra, cast này thất bại và biểu thức ước lượng là null. Một toán tử dynamic_cast thực hiện các cast trên các kiểu đa hình và có thể ép một con trỏ A* thành một con trỏ B* chỉ khi đối tượng đang được trỏ tới thực sự là một đối tượng B.

reinterpret_cast<kieu_du_lieu> (bieu_thuc): Toán tử reinterpret_cast trong C++ thay đổi 1 con trỏ tới bất kỳ kiểu con trỏ khác. Nó cũng cho phép ép kiểu từ con trỏ tới một kiểu integer và ngược lại.

static_cast<kieu_du_lieu> (bieu_thuc): Toán tử static_cast trong C++ thực hiện một cast không có tính đa hình. Ví dụ, nó có thể được dùng để ép kiểu một con trỏ lớp cơ sở thành một con trỏ lớp kế thừa.

Tất cả toán tử ép kiểu trên sẽ được sử dụng trong lúc làm việc với lớp và đối tượng. Bây giờ, bạn thử ví dụ sau để hiểu toán tử ép kiểu đơn giản trong C++. Copy và paste chương trình C++ sau trong tệp test.cpp, sau đó biên dịch và chạy chương trình:

#include <iostream>
using namespace std;
 
main()
{
   double a = 15.65653;
   float b = 9.02;
   int c ;
 
   c = (int) a;
   cout << "Dong 1: Gia tri cua (int)a la: " << c << endl ;
   
   c = (int) b;
   cout << "Dong 1: Gia tri cua (int)b la: " << c << endl ;
   
   return 0;
}

Chạy chương trình C++ trên sẽ cho kết quả như hình sau:

Ép Kiểu Trong C++ Là Gì
Ép Kiểu Trong C++ Là Gì

II. Cách Ép Kiểu Dữ Liệu Trong C++


III. Ép Kiểu Class Trong C++

Ép kiểu (Casting) là quá trình convert từ kiểu dữ liệu A sang kiểu dữ liệu B. C++ có 2 kiểu casting.

Implicit conversion: việc ép kiểu được thực hiện tự động bởi compiler.

int iVar = 10;
float fVar = iVar; //fVar = 10.00

Explicit conversion: ép kiểu được thực hiện bởi lập trình viên.

int iVar = 20;
float fVar = (float)iVar / 10;

Ngôn ngữ C++ support 5 toán tử ép kiểu.
– static_cast
– const_cast
– reinterpret_cast
– dynamic_cast

static_cast

Ví dụ 1:

// static_cast_Operator.cpp  
// compile with: /LD  
class B {};  
   
class D : public B {};  
   
void f(B* pb, D* pd) 
{  
   D* pd2 = static_cast<D*>(pb);   // Not safe, D can have fields  
                                   // and methods that are not in B.  
   
   B* pb2 = static_cast<B*>(pd);   // Safe conversion, D always  
                                   // contains all of B.  
}

Trong ví dụ 1

– Line B* pb2 = static_cast<B*>(pd); an toàn vì các thuộc tính và method của class B đều thuộc class D.
– Line D* pd2 = static_cast<D*>(pb); không an toàn vì class D có các thuộc tính và method mà class B không có. Tuy nhiên, câu lệnh này không báo lỗi khi chạy runtime vì toán tử static_cast không có check runtime (khác với toán tử dynamic_cast). Điều thực sự nguy hiểm khi sử dụng *pd2 truy cập tới thuộc tinh và method chỉ thuộc lớp D và không thuộc lớp B –> Chương trình crash do ACCESS VIOLATION.

Ví dụ 2:

// static_cast_Operator_2.cpp  
// compile with: /LD /GR  
class B 
{  
public:  
   virtual void Test(){}  
};  
class D : public B {};  
   
void f(B* pb) 
{  
   D* pd1 = dynamic_cast<D*>(pb);  
   D* pd2 = static_cast<D*>(pb);  
}

Trong ví dụ 2

– Nếu pb thực sự trỏ tới đối tượng class D, thì pd1 và pd2 sẽ có cùng giá trị, pd1 và pd2 sẽ có cùng giá trị nếu pd == 0 (NULL).
– Nếu pb trỏ tới đối tượng class B, thì dynamic_static sẽ trả về 0, nhưng static_cast không thể detect được vấn đề này. Do vậy, trong trường hợp sử dụng static_cast, lập trình viên phải kiểm tra nếu pb trỏ tới đối tượng class D thì mới trả về con trỏ trỏ tới class D.

Ví dụ 3:

// static_cast_Operator_3.cpp  
// compile with: /LD /GR  
typedef unsigned char BYTE;  
   
void f() 
{  
   char ch;  
   int i = 300;  
   float f = 2.5;  
   double dbl;  
   
   ch = static_cast<char>(i);   // int to char  
   dbl = static_cast<double>(f);   // float to double  
   i = static_cast<BYTE>(ch);  
}

Trong ví dụ 3,

– Toán tửstatic_cast được sử dụng để ép kiểu cho các kiểu dữ basic. Từ int –> char, float –> double, char –> int.
– Câu lệnh “ch = static_cast(i); // int to char” gây ra mất dữ liệu vì kiểu char (1 byte) không đủ chứa kiểu int (4 bytes). Do vậy, chỉ ép kiểu từ kiểu dữ liệu NHỎ –> kiểu dữ liệu TO để tránh convert sai.

const_cast

const_cast < type-id > ( expression )

// expre_const_cast_Operator.cpp  
// compile with: /EHsc  
#include <iostream>  
   
using namespace std;  
class CCTest 
{  
public:  
   void setNumber( int );  
   void printNumber() const;  
private:  
   int number;  
};  
   
void CCTest::setNumber( int num ) { number = num; }  
   
void CCTest::printNumber() const
{  
   cout << "\nBefore: " << number;  
   const_cast< CCTest * >( this )->number--;  
   cout << "\nAfter: " << number;  
}  
   
int main() 
{  
   CCTest X;  
   X.setNumber( 8 );  
   X.printNumber(); 
   system("pause");
}
Ép Kiểu Class Trong C++
Ép Kiểu Class Trong C++

IV. Ép Kiểu Tường Minh Trong C++

Ép kiểu tường minh (Explicit type conversion) là quá trình chuyển đổi kiểu dữ liệu một cách tường minh (rõ ràng) bởi lập trình viên, sử dụng toán tử ép kiểu (casting operator) để thực hiện việc chuyển đổi.

Trong C++, có 5 cách ép kiểu tường minh:

  • C-style casts
  • Static casts
  • Const casts
  • Dynamic casts
  • Reinterpret casts

Phạm vi bài học này sẽ nói về C-style casts và Static casts, 2 cách phổ biến nhất trong C++.

Dynamic casts, Const casts và Reinterpret casts cần những kiến thức chuyên sâu hơn, nên sẽ được bỏ qua trong bài học này.

C-style casts

Trong ngôn ngữ C chuẩn, ép kiểu được thực hiện thông qua toán tử (), và tên kiểu dữ liệu cần chuyển được đặt bên trong.

Ví dụ:

#include <iostream>
using namespace std;

int main()
{
   int n1 = 3;
   int n2 = 2;
   double d = (double)n1 / n2;

   cout << d << endl;

   return 0;
}

Trong chương trình trên, trình biên dịch (compiler) chuyển đổi biến n1 từ kiểu int sang kiểu double thông qua ép kiểu tường minh C-style. Sau đó biểu thức có 2 toán hạng có kiểu double và kiểu int, nên toán hạng kiểu int sẽ được chuyển đổi ngầm định sang kiểu double. Vì vậy, kết quả của biểu thức là phép chia giữa 2 số chấm động kiểu double.

Ngôn ngữ C++ cho phép thực hiện ép kiểu tường minh C-style với cú pháp như một lời gọi hàm:

int n1 = 3;
int n2 = 2;
double d = double(n1) / n2;

Ép kiểu tường minh C-style không được trình biên dịch (compiler) kiểm tra tại thời điểm biên dịch (compile time), nên trình biên dịch sẽ không đưa ra những cảnh báo trong những trường hợp chuyển đổi không đúng

Chú ý: Tránh sử dụng ép kiểu tường minh C-style.

static_cast

Ngôn ngữ C++ có 1 toán tử ép kiểu gọi là static_cast. Bạn đã biết đến nó trong bài KIỂU KÝ TỰ TRONG C++ (Character):

#include <iostream>
#include <iomanip>        // for std::setprecision()
using namespace std;

int main()
{
   int n{ 75 };
   cout << static_cast<char>(n) << endl; // in ký tự với mã ASCII 75

   char ch{ 'K' };
   cout << static_cast<int>(ch) << endl; // in mã ASCII của ký tự 'K'
   return 0;
}

Chương trình trên sử dụng toán tử ép kiểu static cast trong C++ để in một ký tự từ một số nguyên và ngược lại.

Sử dụng static cast trong biểu thức:

Ví dụ:

#include <iostream>
using namespace std;

int main()
{
   int n1 = 3;
   int n2 = 2;
   double d = static_cast<double>(n1) / n2;

   cout << d << endl;

   return 0;
}

Ưu điểm của toán tử static_cast là nó yêu cầu compiler kiểm tra kiểu dữ liệu tại thời điểm biên dịch chương trình, hạn chế được những lỗi ngoài ý muốn.

Chú ý: Nên sử dụng toán tử static_cast thay vì ép kiểu C-style.

 Ép Kiểu Tường Minh Trong C++
Ép Kiểu Tường Minh Trong C++

V. Ép Kiểu Con Trỏ Trong C++

 

VI. Ép Kiểu Float Trong C

Chắc hẳn khi mới bắt đầu tập tành với C/C++ ai cũng gặp trường hợp phải ép kiểu int sang float và ngược lại. Vậy bài viết này mình sẽ hướng dẫn các bạn cách ép kiểu nguyên sang kiểu thực trong C/C++.

Ép từ kiểu nguyên sang kiểu thực

Ép kiểu int sang float

Có nhiều trường hợp chúng ta phải ép kiểu từ int sang float như ví dụ dưới đây

Bài toán: Nhập vào hai số nguyên dương a và b. Hãy xuất ra kết quả a/b.

#include<iostream>
 
using namespace std;
 
int main()
{
    int a, b;
    float kq;
    cout << "Nhap a: "; cin >> a;
    cout << "Nhap b: "; cin >> b;
    if (!b) {// Hoặc if(b==0)
        cout << "Mau phai khac 0 !";
        return 0;
    }
    kq = a / b;
    cout << "Ket qua la: " << kq << endl;
    return 0;
}
Nhap a: 2
Nhap b: 3
Ket qua la: 0

Trong trường hợp trên ta bắt buộc phải ép kiểu int sang float. Cú pháp ép kiểu như sau:

 
kq = (float)a / (float)b;
kq = float(a) / float(b);

Ở trên có hai cách ép kiểu nhưng mình khuyên các bạn nên dùng cách dưới, nhìn dễ hiểu hơn.

Cùng xem lại đoạn code ở trên nhé

 
#include<iostream>
 
using namespace std;
 
int main()
{
    int a, b;
    float kq;
    cout << "Nhap a: "; cin >> a;
    cout << "Nhap b: "; cin >> b;
    if (!b) {// Hoặc if(b==0)
        cout << "Mau phai khac 0 !";
        return 0;
    }
    //kq = (float)a / (float)b;
    kq = float(a) / float(b);
    cout << "Ket qua la: " << kq << endl;
    return 0;
}
Nhap a: 2
Nhap b: 3
Ket qua la: 0.666667

Ép kiểu int sang double

Cách làm cũng tương tự như trên mà thôi.

Ép từ kiểu thực sang kiểu nguyên

Ép kiểu float sang int

Ta có thể ép kiểu dữ liệu như sau:

 
#include<iostream>
 
using namespace std;
 
int main()
{
    float a = 3.5f;
    int b = int(a);
    cout << "Sau khi ep kieu: " << b << endl;
    return 0;
}
Sau khi ep kieu: 3

Lưu ý: Khi ép kiểu từ int sang float thì chỉ nhận được các chữ số trước dấu phẩy mà thôi. Chứ không làm tròn lên nhé.

Ví dụ: int a = float(8.9) thì a sẽ nhận giá trị 8 mà thôi.

Ép kiểu double sang int

Tương tự như ép kểu float sang int.

Ép Kiểu Float Trong C
Ép Kiểu Float Trong C

VII. Ép Kiểu Int Sang String Trong C++

Hướng dẫn cách chuyển int sang string trong C++. Bạn sẽ học được cách sử dụng hàm to_string() trong C++ sau bài học này.

Chúng ta có 2 phương pháp để chuyển int sang string trong C++ như sau:

  • Sử dụng hàm template (trước C++11)
  • Sử dụng hàm to_string (từ C++11)

Chuyển float và int sang string trong C++ bằng hàm template

Phương pháp đầu tiên cũng để chuyển int sang string trong C++ đó chính là sử dụng hàm template sau đây:

#include <sstream>
template <typename T> std::string tostr(const T& t)
{
    std::ostringstream os; os<<t; return os.str();
}

Hàm template trên có tác dụng chuyển đổi kiểu số bao gồm cả int lẫn float sang kiểu string. Sau khi đã khai báo template này, chúng ta có thể sử dụng nó nhiều lần trong chương trình.

Ví dụ cụ thể, chúng ta có thể chuyển float và int sang string như chương trình sau. Lưu ý chúng ta sử dụng tới hàm typeid.name() để kiểm tra kiểu của dữ liệu trước và sau lúc đổi thay bằng hàm template.

#include <iostream>
#include <sstream>  
#include <typeinfo>

using namespace std;
 
template <typename T> string tostr(const T& t)
{
    ostringstream os; os<<t; return os.str();
}

 
int main() {
    int a = 123;
    float b = 3.45;

    cout << "Kieu cua a: "<< typeid(a).name() <<endl;
    cout << "Kieu cua b: "<<typeid(b).name() <<endl;
    
    //Kiểu sau khi thay đổi
    cout << "Kieu thay doi cua a: "<< typeid(tostr(123)).name() <<endl;
    cout << "Kieu thay doi cua b: "<<typeid(tostr(3.1415)).name() <<endl;
    return 0;
}

Kết quả, hai biến a và b với kiểu int và float đã được chuyển sang kiểu string bằng hàm tostr như sau:

Kieu cua a: i
Kieu cua b: f
Kieu thay doi cua a: NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Kieu thay doi cua b: NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE

Chuyển int sang string trong C++ bằng hàm to_string

Để dùng hàm template ở trên, chúng ta đều cần khai báo template ở đầu mỗi chương trình, và chuyện này thật là rườm rà phải không nào?

Đó là lý do mà từ phiên bản C++11 trở đi, song hành cùng với hàm template ở trên thì các nhà phát triển C++ đã thêm vào 1 hàm mới có chức năng tương tự nhưng lại có thể sử dụng dễ dàng hơn, đó chính là hàm to_string.

Hàm to_string là 1 hàm được thêm vào từ phiên bản C++11, có tác dụng chuyển số sang string trong C++. Hàm to_string có thể chuyển tất cả các định dạng kiểu số như int, float, double sang string trong C++ với cú pháp đơn giản và ngắn gọn.

Chúng ta sử dụng hàm to_string() trong C++ với cú pháp sau đây:

to_string(num);

Trong đó num là số cần chuyển sang kiểu chuỗi string, và num có thể ở bất kiểu số nào, ví dụ như int, float, double hay short chẳng hạn.

Ví dụ cụ thể, chúng ta có thể chuyển int sang string trong C++ bằng hàm to_string và kiểm tra kiểu trước và sau khi chuyển đổi bằng hàm typeid.name() như sau:

#include <iostream>
#include <typeinfo>

using namespace std;

int main() {
    int a = 123;
    float b = 3.45;

    cout << "Kieu cua a: "<< typeid(a).name() <<endl;
    cout << "Kieu cua b: "<<typeid(b).name() <<endl;
    
    //Kiểu sau khi thay đổi
    cout << "Kieu thay doi cua a: "<< typeid(to_string(123)).name() <<endl;
    cout << "Kieu thay doi cua b: "<<typeid(to_string(3.1415)).name() <<endl;
    return 0;
}

Kết quả, hai biến a và b với kiểu int và float đã được chuyển sang kiểu string bằng hàm to_string như sau:

Kieu cua a: i
Kieu cua b: f
Kieu thay doi cua a: NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Kieu thay doi cua b: NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Ép Kiểu Int Sang String Trong C++
Ép Kiểu Int Sang String Trong C++

VIII. Ép Kiểu String Sang Char Trong C+

 

IX. Ép Kiểu Int Sang Char Trong C++

X. Phân Loại Ép Kiểu Trong C++

Phân loại ép kiểu trong C++

Trong C++, có hai loại ép kiểu dữ liệu:

  1. Nới rộng (widening): Là quá trình làm tròn số từ kiểu dữ liệu có kích thước nhỏ hơn sang kiểu có kích thước lớn hơn. Kiểu biến đổi này không làm mất thông tin.
  2. Thu hẹp (narrowwing): Là quá trình làm tròn số từ kiểu dữ liệu có kích thước lớn hơn sang kiểu có kích thước nhỏ hơn. Kiểu biến đổi này có thể làm mất thông tin

1. Nới rộng (widening)

Phân Loại Ép Kiểu Trong C++
Phân Loại Ép Kiểu Trong C++

Nới rộng (widening): Là quá trình làm tròn số từ kiểu dữ liệu có kích thước nhỏ hơn sang kiểu có kích thước lớn hơn. Kiểu biến đổi này không làm mất thông tin. Ví dụ chuyển từ int sang float. Chuyển kiểu loại này có thế được thực hiện ngầm định bởi trình biên dịch.

Ví dụ:

#include <iostream>
 
using namespace std;
  
int main() {
    int i = 100;
    long l = i;    // khong yeu cau chi dinh ep kieu
    float f = l;   // khong yeu cau chi dinh ep kieu
    cout << "Gia tri Int: " << i << endl;
    cout << "Gia tri Long: " << l << endl;
    cout << "Gia tri Float: " << f << endl;
    return 0;
}

Kết quả:

Giá trị Int: 100
Giá trị Long: 100
Giá trị Float:  100

2.Thu hẹp (narrowwing)

Phân Loại Ép Kiểu Trong C++
Phân Loại Ép Kiểu Trong C++

Thu hẹp (narrowwing): Là quá trình làm tròn số từ kiểu dữ liệu có kích thước lớn hơn sang kiểu có kích thước nhỏ hơn. Kiểu biến đổi này có thể làm mất thông tin như ví dụ ở trên. Chuyển kiểu loại này không thể thực hiện ngầm định bởi trình biên dịch, người dùng phải thực hiện chuyển kiểu tường minh.

Ví dụ:

#include <iostream>
 
using namespace std;
  
int main() {
    double d = 100.04;
    long l = (long) d; // yeu cau chi dinh kieu du lieu (long)
    int i = (int) l; // yeu cau chi dinh kieu du lieu (int)
    cout << "Gia tri Double: " << d << endl;
    cout << "Gia tri Long: " << l << endl;
    cout << "Gia tri Int: " << i << endl;
    return 0;
}

Kết quả:

Giá trị Double: 100.04
Giá trị Long: 100
Giá trị Int:  100

The post Ép Kiểu Trong C++ first appeared on Techacademy.



source https://techacademy.edu.vn/ep-kieu-trong-c/

Nhận xét

Bài đăng phổ biến từ blog này

Vẽ Tam Giác Trong C++

Vẽ tam giác trong C++ là một trong những bài tập lập trình về C++ sử dụng vòng lặp khá hay giúp các bạn luyện tư duy code cũng như cách sử dụng vòng lặp. Dưới đây là một số lời giải các bài tập vẽ tam giác trong C++ I. Vẽ Tam Giác Cân Trong C++ Viết chương trình C++ sử dụng ký tự * để vẽ tam giác vuông cân trong C++.Chúng ta sử dụng hai vòng lặp lồng nhau để giải bài toán này. Lời Giải: #include <stdio.h> #include <stdlib.h> int main() { int n; int q = 0; printf("Chuong trinh nay se in ra tam giac can\n"); printf("Nhap chieu cao tam giac cua ban: \n"); scanf("%d",&n); while (n > 0) { for (int i = 1; i<n; i++) printf("%c", ' '); for (int k = 0; k <= q; k ++) printf("%c", '*'); n -- ; q += 2 ; printf("\n"); } return 0; } II. Vẽ Hình Tam Giác Trong C++ Viết một chương trình in ra hình

Nên học C hay C++ ? Lựa chọn nào tốt hơn

Bạn đang mới học lập trình và đang phân vân nên học lập trình C hay C++ , bài viết dưới đây của Tehcacademy.edu.vn sẽ phần nào giải đáp cho bạn thắc mắc trên.  I. Nên học ngôn ngữ lập trình C hay C++ Nếu bạn đang phân vẫn lựa chọn nên học C hay C++ thì dưới đây là một số ưu điểm và nhược điểm của ngôn ngữ lập trình C và C++. Dựa trên đánh giá này, giúp bạn lựa chọn nên học lập trình C hay C++ 1, Ưu điểm và nhược điểm của ngôn ngữ lập trình C, C++ Dưới đây là một số ưu điểm, nhược điểm của ngôn ngữ c và c++: C, C++ đều có những ưu điểm và nhược điểm riêng + Ngôn ngữ lập trình C Ưu điểm : + Hiệu suất cao Mỗi một ngôn ngữ đều dựa vào khả năng sử dụng bộ nhớ để đánh giá hiệu suất. Đây chính là ưu điểm đầu tiên của C, nó có thể chạy mượt mà trên những hệ thống giới hạn về dung lượng, lý do là vì ngay từ đầu C được thiết kế với mục đích thay thế ASM trong các hệ thống bộ nhớ cực hạn chế thập niên 1960. + Tính linh hoạt Lập trình C có 2 tính linh hoạt và là 2 ưu điểm nổi bật củ

Tìm Phần Tử Xuất Hiện Nhiều Nhất Trong Mảng C++

Tìm phần tử xuất hiện nhiều nhất trong mảng là một vấn đề phổ biến trong lập trình C++. Để giải quyết vấn đề này, bạn có thể sử dụng một số phương pháp khác nhau như sử dụng bảng băm (hash table), sắp xếp mảng và duyệt qua mảng. Cùng techacademy đi tìm hiểu chi tiết chủ đề này ngay bài viết bên dưới đây nhé. I. Tìm Phần Tử Xuất Hiện Nhiều Nhất Trong Mảng C++ Trong lập trình C++, việc tìm ra phần tử xuất hiện nhiều nhất trong một mảng là một vấn đề phổ biến và quan trọng. Điều này thường được thực hiện thông qua việc sử dụng các thuật toán và cấu trúc dữ liệu phù hợp. Chúng ta sẽ thảo luận về cách thực hiện điều này một cách hiệu quả trong ngôn ngữ lập trình C++. 1. Sử dụng Bảng Băm (Hash Map): Một cách phổ biến để giải quyết vấn đề này là sử dụng bảng băm. Chúng ta có thể duyệt qua mảng, đếm số lần xuất hiện của mỗi phần tử và lưu trữ chúng trong một bảng băm. 2. Sắp Xếp và Đếm: Một cách khác là sắp xếp mảng và sau đó duyệt qua mảng để đếm số lần xuất hiện của mỗi phần tử liên ti