DÙNG std::array TRONG C++
Dưới đây là ví dụ:
#include <iostream>
#include <array>
int main() {
// Cách 1: Khai báo tường minh (C++11)
std::array<int, 5> arr1 = {1, 2, 3, 4, 5};
// Cách 2: CTAD - Class Template Argument Deduction (C++17 trở lên)
// Trình biên dịch tự suy luận kiểu 'int' và kích thước '3'
std::array arr2 = {10, 20, 30};
// Cách 3: Sử dụng std::to_array (C++20/23) - Rất hữu ích khi làm việc với chuỗi hoặc mảng C cũ
auto arr3 = std::to_array("DuyTan");
return 0;
}
Các Thao Tác Cốt Lõi Và Độ Phức Tạp
Trong Cấu trúc dữ liệu, chúng ta luôn phải quan tâm đến Big O. std::array cung cấp các thao tác với chi phí cực thấp:
-
Truy cập phần tử (
operator[]hoặc.at()): Mất $O(1)$ thời gian. Khuyến khích dùng.at()trong giai đoạn debug vì nó kiểm tra tràn viền (Bounds checking), tránh lỗi Segmentation Fault nguy hiểm. -
Lấy kích thước (
.size()): Mất $O(1)$ thời gian, luôn trả về hằng số (constexpr). -
Truy cập con trỏ gốc (
.data()): Rất quan trọng khi cần tương tác với các hàm API cũ viết bằng C.
std::array<int, 4> nums = {5, 10, 15, 20};
int x = nums[1]; // Rất nhanh, O(1)
int y = nums.at(2); // An toàn, ném ngoại lệ std::out_of_range nếu index sai
C++23 giới thiệu thư viện <print> và hỗ trợ in trực tiếp container. Kết hợp với thư viện <ranges>, thao tác trên mảng trở nên rõ ràng và ít lỗi hơn việc dùng vòng lặp for truyền thống.
#include <array>
#include <ranges>
#include <algorithm>
#include <print> // Tính năng mới của C++23
int main() {
std::array data = {8, 2, 5, 9, 1};
// Sắp xếp mảng sử dụng ranges (Không cần data.begin(), data.end() dài dòng)
std::ranges::sort(data);
// C++23 cho phép in trực tiếp nội dung mảng ra console hoặc file một cách dễ dàng
std::println("Mảng sau khi sắp xếp: {}", data);
// Output dự kiến: Mảng sau khi sắp xếp: [1, 2, 5, 8, 9]
// Sử dụng Views để tạo 파t toán Pipeline (Biến đổi dữ liệu lười - Lazy evaluation)
auto squares = data | std::views::transform([](int x){ return x * x; });
std::println("Bình phương các phần tử: {}", squares);
}
Tại Sao Chọn std::array Thay Vì std::vector?
Khi phân tích giải thuật, ta cần đưa ra quyết định chọn cấu trúc dữ liệu phù hợp:
-
Nếu kích thước mảng đã biết trước và nhỏ (VD: Mảng đếm tần số ký tự $256$ phần tử, bảng băm tĩnh): Dùng
std::array. Bộ nhớ nằm trên Stack, tốc độ cấp phát là hằng số $O(1)$ tức thời, không lo phân mảnh bộ nhớ (Memory fragmentation). -
Nếu kích thước thay đổi linh hoạt (Dynamic): Dùng
std::vector(nằm trên Heap).

