Bỏ qua để đến nội dung

So sánh Array, Vector, Pair, Map, Set

Sau khi đã học qua từng cấu trúc dữ liệu, bài này tổng hợp lại để giúp bạn chọn đúng công cụ cho từng bài toán cụ thể.

Cấu trúc Kích thước Trùng lặp? Có thứ tự? Truy cập
array (C-style) Cố định Theo chỉ số arr[i]
std::vector Thay đổi được Theo chỉ số (thứ tự thêm vào) v[i], .at(i)
std::pair/std::tuple Cố định (2 hoặc nhiều giá trị) Theo vị trí khai báo .first/.second, std::get<i>
std::map Thay đổi được Khóa không trùng Sắp xếp theo khóa m[khóa], .find()
std::unordered_map Thay đổi được Khóa không trùng Không đảm bảo m[khóa], .find()
std::set Thay đổi được Không trùng Sắp xếp tăng dần .find(), .count()
std::unordered_set Thay đổi được Không trùng Không đảm bảo .find(), .count()

Câu hỏi để chọn đúng cấu trúc dữ liệu

Phần tiêu đề “Câu hỏi để chọn đúng cấu trúc dữ liệu”

1. Dữ liệu có kích thước cố định, biết trước lúc biên dịch? → Mảng C-style (int arr[5]) - hiếm khi cần trong code hiện đại trừ trường hợp đặc biệt.

2. Cần một danh sách có thể thêm/bớt phần tử?std::vector - lựa chọn mặc định cho hầu hết trường hợp cần danh sách.

3. Chỉ cần gộp 2-3 giá trị lại, không cần thay đổi số lượng?std::pair (2 giá trị) hoặc std::tuple (nhiều hơn), hoặc struct nếu dữ liệu có ý nghĩa lâu dài.

4. Cần tra cứu giá trị thông qua một “khóa” thay vì chỉ số?std::map (cần thứ tự) hoặc std::unordered_map (chỉ cần tra cứu nhanh).

5. Cần đảm bảo các phần tử không trùng lặp?std::set (cần thứ tự) hoặc std::unordered_set (chỉ cần tra cứu nhanh).

#include <vector>
#include <map>
#include <set>
#include <iostream>
int main() {
// Danh sách điểm số của một học sinh (có thể thêm điểm mới) -> vector
std::vector<int> scores = {85, 90, 78};
scores.push_back(95);
// Tra cứu điểm số theo tên học sinh -> map
std::map<std::string, int> student_scores = {{"Alice", 90}, {"Bob", 85}};
// Danh sách các môn học học sinh ĐÃ đăng ký (không trùng lặp) -> set
std::set<std::string> enrolled_courses = {"Math", "Physics", "Math"}; // "Math" chỉ xuất hiện 1 lần
std::cout << scores.size() << std::endl; // 4
std::cout << student_scores["Alice"] << std::endl; // 90
std::cout << enrolled_courses.size() << std::endl; // 2
return 0;
}
  • vector: danh sách có thể thay đổi kích thước, truy cập theo chỉ số - lựa chọn mặc định phổ biến nhất
  • pair/tuple: gộp một số lượng cố định giá trị (2 hoặc nhiều hơn), thường dùng cho giá trị trả về của hàm
  • map/unordered_map: tra cứu giá trị thông qua khóa
  • set/unordered_set: tập hợp các giá trị duy nhất, không trùng lặp
  • Phiên bản unordered_* luôn nhanh hơn phiên bản có thứ tự, nhưng đánh đổi việc mất thứ tự phần tử