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úcKích thướcTrùng lặp?Có thứ tự?Truy cập
array (C-style)Cố địnhCóTheo chỉ sốarr[i]
std::vectorThay đổi đượcCóTheo chỉ số (thứ tự thêm vào)v[i], .at(i)
std::pair/std::tupleCố định (2 hoặc nhiều giá trị)CóTheo vị trí khai báo.first/.second, std::get<i>
std::mapThay đổi đượcKhóa không trùngSắp xếp theo khóam[khóa], .find()
std::unordered_mapThay đổi đượcKhóa không trùngKhông đảm bảom[khóa], .find()
std::setThay đổi đượcKhông trùngSắp xếp tăng dần.find(), .count()
std::unordered_setThay đổi đượcKhông trùngKhô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ử