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ể.
Bảng so sánh tổng quan
Phần tiêu đề “Bảng so sánh tổng quan”| Cấu trúc | Kích thước | Trùng lặp? | Có thứ tự? | Truy cập |
|---|---|---|---|---|
array (C-style) |
Cố định | Có | Theo chỉ số | arr[i] |
std::vector |
Thay đổi được | 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ị) | Có | 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).
Ví dụ minh họa lựa chọn
Phần tiêu đề “Ví dụ minh họa lựa chọn”#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;}Tổng kết
Phần tiêu đề “Tổng kết”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ấtpair/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àmmap/unordered_map: tra cứu giá trị thông qua khóaset/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ử