C++11中array容器的常见用法

一、概述

在 C++11 中,std::array 是一个新的容器类型,它提供了一个固定大小的数组封装。相比传统的 C 风格数组,std::array 提供了更多的功能和类型安全性,并且更符合现代 C++ 的风格。std::array 是一个模板类,定义在 <array> 头文件中,它封装了固定大小的数组,并提供了更方便的访问和操作方法。

二、std::array的特点

  • 固定大小:std::array 的大小在编译时确定,不能在运行时动态改变。
  • 类型安全:由于 std::array 是模板类,它保证了元素的类型安全,且可以使用类型推断。
  • 支持标准容器接口:std::array 提供了与其他标准容器类似的接口,如 begin(), end(), size(), empty(), at(), [] 等。
  • 可以与 C 风格数组互操作:std::array 可以通过 data() 方法访问底层的 C 风格数组。

三、std::array的定义与初始化

std::array 是一个模板类,其模板参数为元素类型和容器大小。
1. 定义与初始化

#include <iostream>
#include <array>

int main() {
   
   
    // 定义一个包含 5 个整数的 std::array
    std::array<int, 5> arr = {
   
   1, 2, 3, 4, 5};

    // 访问元素
    std::cout << "arr[0] = " << arr[0] << std::endl;

    // 使用范围 for 循环打印元素
    for (const auto& elem : arr) {
   
   
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    return 0;
}

2. 使用 fill() 方法初始化
可以使用 fill() 方法为所有元素赋值相同的值:

std::array<int, 5> arr;
arr.fill(10);  // 所有元素被初始化为 10

3. 通过列表初始化
std::array 还可以通过列表初始化进行初始化:

std::array<int, 3> arr = {
   
   1, 2, 3};  // 列表初始化

三、std::array的常用成员函数

std::array 提供了很多类似于其他 STL 容器的成员函数,包括获取容器大小、访问元素、检查是否为空等。
1. size():返回数组的大小
std::array 的 size() 函数用于返回数组中元素的数量。与 std::vector 不同,std::array 的大小是固定的(在编译时已知),所以 size() 返回的是数组的元素总数,而不是动态变化的长度。

#include <iostream>
#include <array>

int main() {
   
   
    
<think>好的,我现在需要回答用户关于C++中STL容器用法的问题。首先,我要回忆一下STL容器的主要类型和它们的用途。STL容器分为顺序容器、关联容器容器适配器和其他容器几大类。每个容器都有其特定的应用场景和操作方式。 用户要求结构清晰的回答,所以我需要分门别类地介绍每个容器,包括它们的常用操作、时间复杂度以及适用场景。同时,用户提到要使用中文,并且数学表达式需要用$...$或$$...$$格式,但在这个问题中可能涉及数学的地方不多,不过如果有算法复杂度的话,可能需要用到,比如$O(1)$、$O(n)$等。 首先,顺序容器包括vector、deque、list、forward_list、arraystring。我需要逐一介绍它们的特性和常用方法。例如,vector类似于动态数组,支持随机访问;list是双向链表,插入删除高效,但不支持随机访问。需要注意各个容器的时间复杂度差异,比如vector在尾部插入是$O(1)$,而在中间插入是$O(n)$。 接下来是关联容器,分为有序和无序两种。有序的如set、map、multiset、multimap,基于红黑树实现,操作复杂度为$O(\log n)$;无序的如unordered_set、unordered_map等,基于哈希表,平均$O(1)$,最坏$O(n)$。要说明它们的区别和使用场景,比如需要有序遍历时用有序容器,追求快速访问用无序容器容器适配器包括stack、queue、priority_queue,它们基于其他容器实现,比如默认情况下stack用deque,priority_queue用vector。需要解释它们的特性和限制,比如stack只能后进先出,queue先进先出,priority_queue按优先级出队。 然后,可能需要提到C++17引入的string_view和C++20的span,虽然不是传统容器,但用于视图,避免复制数据。此外,其他容器如bitset,用于位操作,但可能不常用,可以简要提及。 在介绍每个容器时,要给出代码示例,比如vector的push_back、emplace_back,map的insert和operator[]的区别。注意强调各容器的迭代器类型,比如随机访问迭代器、双向迭代器等,这对算法使用很重要。 还需要提醒用户一些常见问题,比如vector的迭代器失效问题,当元素增加导致重新分配内存时,原有迭代器会失效。map和unordered_map在插入和删除时的注意事项,比如unordered_map的哈希冲突可能影响性能。 最后,总结如何根据需求选择合适的容器,比如需要快速随机访问选vector,频繁中间插入选list,需要键值对快速查找用map或unordered_map。同时,强调实际开发中结合具体场景选择,比如元素数量、操作类型(插入、删除、访问)和内存考虑。 现在,需要检查是否有遗漏的容器或者特性,比如C++11引入的array容器,它是固定大小的数组,相比内置数组更安全。还有forward_list是单链表,节省内存但功能较少。string作为容器,虽然主要用于字符串,但支持类似vector的操作。 另外,关于时间复杂度,要确保正确无误,比如unordered_map的平均O(1)和红黑树的O(log n)。对于适配器,比如priority_queue的底层实现是堆,其插入和删除的时间复杂度是O(log n)。 可能还需要提到容器的通用操作,比如size()、empty()、swap(),以及C++11引入的emplace方法,避免临时对象构造,提高效率。比较不同容器的迭代器失效规则,这也是使用容器时需要注意的重要点。 总结下来,整个回答需要结构清晰,分类明确,每个容器给出简要介绍、常用操作、时间复杂度和示例代码。同时,最后给出选择容器的指导原则,帮助用户在实际应用中做出合适的选择。</think>以下是C++中STL容器的系统化介绍,按类别划分并附详细说明: --- ### 一、顺序容器(Sequence Containers) #### 1. `vector` - **特性**:动态数组,内存连续,支持快速随机访问。 - **时间复杂度**: - 尾部插入/删除:$O(1)$ - 中间插入/删除:$O(n)$ - 随机访问:$O(1)$ - **常用操作**: ```cpp vector<int> v; v.push_back(10); // 尾部插入 v.emplace_back(20); // 高效尾部构造(C++11) v.pop_back(); // 尾部删除 v[0]; // 随机访问 v.insert(v.begin(), 5); // 中间插入(慎用,低效) ``` #### 2. `deque` - **特性**:双端队列,支持头尾高效插入/删除,内存分段连续。 - **时间复杂度**: - 头尾插入/删除:$O(1)$ - 中间操作:$O(n)$ - **常用操作**: ```cpp deque<int> dq; dq.push_front(1); // 头部插入 dq.push_back(2); // 尾部插入 dq.pop_front(); // 头部删除 ``` #### 3. `list` - **特性**:双向链表,支持高效任意位置插入/删除。 - **时间复杂度**: - 插入/删除:$O(1)$(已知位置) - 随机访问:$O(n)$ - **常用操作**: ```cpp list<int> lst; lst.push_back(3); lst.insert(++lst.begin(), 5); // 在第二个位置插入 lst.splice(lst.end(), other_lst); // 合并链表 ``` #### 4. `forward_list` - **特性**:单向链表,更省内存,仅支持单向遍历。 - **时间复杂度**:与`list`类似,但无反向操作。 --- ### 二、关联容器(Associative Containers) #### 1. 有序容器(基于红黑树) - **`set`/`multiset`** - **特性**:有序唯一键集合(`multiset`允许重复)。 - **时间复杂度**:$O(\log n)$ ```cpp set<int> s; s.insert(10); if (s.find(10) != s.end()) { /* 存在 */ } ``` - **`map`/`multimap`** - **特性**:键值对映射(`multimap`允许多个相同键)。 - **常用操作**: ```cpp map<string, int> m; m["apple"] = 5; // 插入或修改 auto it = m.emplace("banana", 3); // 高效构造(C++11) ``` #### 2. 无序容器(基于哈希表) - **`unordered_set`/`unordered_multiset`** - **特性**:哈希实现,依赖`hash`函数和`==`运算符。 - **时间复杂度**:平均$O(1)$,最坏$O(n)$。 - **`unordered_map`/`unordered_multimap`** - **示例**: ```cpp unordered_map<string, int> um; um.reserve(100); // 预分配桶,减少冲突 um["apple"] = 5; ``` --- ### 三、容器适配器(Container Adapters) #### 1. `stack` - **特性**:后进先出(LIFO),默认基于`deque`。 - **操作**: ```cpp stack<int> s; s.push(10); s.pop(); // 无返回值 ``` #### 2. `queue` - **特性**:先进先出(FIFO),默认基于`deque`。 - **操作**: ```cpp queue<int> q; q.push(20); q.front(); // 访问队首 ``` #### 3. `priority_queue` - **特性**:优先队列(最大堆),默认基于`vector`。 - **时间复杂度**:插入/删除$O(\log n)$ ```cpp priority_queue<int> pq; pq.push(30); pq.top(); // 访问最大值 ``` --- ### 四、其他容器 - **`array`**(C++11): - 固定大小数组,替代原生数组。 ```cpp array<int, 3> arr = {1,2,3}; ``` - **`string`**: - 类似`vector<char>`,专为字符串设计。 ```cpp string str = "hello"; str.substr(1, 3); // "ell" ``` --- ### 五、容器选择原则 1. **随机访问需求高** → `vector`/`deque` 2. **频繁中间插入/删除** → `list`/`forward_list` 3. **有序快速查找** → `set`/`map` 4. **极速查找(不要求有序)** → `unordered_`系列 5. **特定数据结构需求** → 适配器(如栈、队列) --- ### 六、注意事项 - **迭代器失效**: - `vector`插入可能使所有迭代器失效。 - `map`/`set`删除仅影响当前迭代器。 - **性能陷阱**: - 避免在`vector`中间频繁插入。 - `unordered_map`需设计良好的哈希函数。 通过结合具体场景选择容器,可显著提升代码效率和可维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值