1. 数组

int a[] = {1, 2, 3, 4, 5, 5};

2. Vector

构造函数

* vector<datatype> a;  //empty vector
* vector<datatype> b (no of elements, value of each element); //fixed number of elements with default value
* vector<datatype> c (starting iterator/pointer,ending iterator/pointer); //inserting elements from other data structures
* vector<datatype> d (name of vector to be copied);
* vector<vector<datatype> > matrix(no of rows,vector<datatype>(no of coloumn,default value)) //Declaring a 2D array

vector array{1,2,3,4};

注意: vector<datatype> v[10]; , following declaration isn't a vector with 10 elements but an array of size ten having vector elements.

methods:

  • at(index) # 等同于 "[]" operator
  • clear()
  • push_back(item)
  • pop_back()
  • front()
  • back()
  • empty()
  • size()
  • resize(n)

3. List

methods:

  • front()
  • back()
  • begin()
  • end()
  • rbegin()
  • rend()
  • empty()
  • size()
  • resize()
  • max_size()

  • push_back()
  • push_front()
  • insert() # 任意位置插入
  • pop_back()
  • pop_front()
  • clear()
  • erase() # 删除一个元素或一个区域的元素(两个重载)
  • remove() # 删除链表中匹配值的元素(匹配元素全部删除)
  • remove_if() # 删除条件满足的元素(遍历一次链表),参数为自定义的回调函数

  • reverse()
  • sort()
  • merge()
  • splice()
  • swap()
  • unique()

3.1. std::forward_list

std::forward_list 是一个列表容器,使用方法和 std::list 基本类似,因此我们就不花费篇幅进行介绍了。

需要知道的是,和 std::list 的双向链表的实现不同,std::forward_list 使用单向链表进行实现, 提供了 O(1) 复杂度的元素插入,不支持快速随机访问(这也是链表的特点), 也是标准库容器中唯一一个不提供 size() 方法的容器。当不需要双向迭代时,具有比 std::list 更高的空间利用率。

4. Tuple

构造函数

* tuple <char, int, float> gk;
* tuple <int,char,float> tup1(20,'g',17.5);
* tuple <char, int, float> gk2 = make_tuple('a', 10, 15.5); int len_tuple = tuple_size<decltype(gk)>::value;
tie(i_val,ch_val,f_val) = tup1;

method:

  • get() # get<0>(gk)
  • make_tuple()
  • tuple_size
  • swap()
  • tie()
  • tuple_cat()

std::get 除了使用常量获取元组对象外,C++14 增加了使用类型来获取元组中的对象:

std::tuple<std::string, double, double, int> t("123", 4.5, 6.7, 8);
std::cout << std::get<std::string>(t) << std::endl;
std::cout << std::get<double>(t) << std::endl; // 非法, 引发编译期错误
std::cout << std::get<3>(t) << std::endl;

4.1. 运行期索引

如果你仔细思考一下可能就会发现上面代码的问题,std::get<> 依赖一个编译期的常量,所以下面的方式是不合法的:

int index = 1;
std::get<index>(t);

那么要怎么处理?答案是,使用 std::variant<>(C++ 17 引入),提供给 variant<> 的类型模板参数 可以让一个 variant<> 从而容纳提供的几种类型的变量(在其他语言,例如 Python/JavaScript 等,表现为动态类型):

#include <variant>
template <size_t n, typename... T>
constexpr std::variant<T...> _tuple_index(const std::tuple<T...>& tpl, size_t i) {
if constexpr (n >= sizeof...(T))
throw std::out_of_range("越界.");
if (i == n)
return std::variant<T...>{ std::in_place_index<n>, std::get<n>(tpl) };
return _tuple_index<(n < sizeof...(T)-1 ? n+1 : 0)>(tpl, i);
}
template <typename... T>
constexpr std::variant<T...> tuple_index(const std::tuple<T...>& tpl, size_t i) {
return _tuple_index<0>(tpl, i);
}
template <typename T0, typename ... Ts>
std::ostream & operator<< (std::ostream & s, std::variant<T0, Ts...> const & v) {
std::visit([&](auto && x){ s << x;}, v);
return s;
}

这样我们就能:

int i = 1;
std::cout << tuple_index(t, i) << std::endl;

4.2. 元组合并

还有一个常见的需求就是合并两个元组,这可以通过 std::tuple_cat 来实现:

auto new_tuple = std::tuple_cat(get_student(1), std::move(t));

4.3. 元祖遍历

我们刚才介绍了如何在运行期通过非常数索引一个 tuple 那么遍历就变得简单了, 首先我们需要知道一个元组的长度,可以:

template <typename T>
auto tuple_len(T &tpl) {
return std::tuple_size<T>::value;
}

这样就能够对元组进行迭代了:

// 迭代
for(int i = 0; i != tuple_len(new_tuple); ++i)
// 运行期索引
std::cout << tuple_index(i, new_tuple) << std::endl;

5. Pair

构造方法:

* pair <data_type1, data_type2> Pair_name (value1, value2);
* pair <data_type1, data_type2> g1; //default
* pair <data_type1, data_type2> g2(1, 'a'); //initialized, different data type
* pair <data_type1, data_type2> g3(1, 10); //initialized, same data type
* pair <data_type1, data_type2> g4(g3); //copy of g3

Pair<string, int> xxx = make_pair(key, value);

methods:

  • operators(=, ==, !=, >=, <=)
  • swap()

6. Sets / Multiset

二者的区别:

Set集合中一个值只能出现一次,而Multiset中一个值可以出现多次。

int a[] = {1, 2, 3, 4, 5, 5};
set<int> s2 (a, a + 6); // s2 = {1, 2, 3, 4, 5}
set<int> s4 (s3.begin(), s3.end());

method:

  • insert()
  • erase()

  • begin()
  • end()
  • clear()
  • count()
  • empty()
  • find()
  • size()
  • contains (C++20) 检查容器是否含有带特定键的元素

6.1. std::unordered_set / std::unordered_multiset

7. Map / Multimap

std::map<int, string> dict = {
{0, "ahts"},
{1, "1234"}
};

method:

map<char, int> map_b(map_a.begin(), map_a.end());
map_a.insert(pair<char, int>('a', 502));
map_a['a'] = 10;
cout << map_a['b'];
cout << map_a.at('b');
map_a.find('b');
map_a.erase('b');

7.1. std::unordered_map / std::unordered_multimap

8. 无序容器

我们已经熟知了传统 C++ 中的有序容器 std::map / std::set ,这些元素内部通过 红黑树 进行实现, 插入和搜索的平均复杂度均为 O(log(size)) 。在插入元素时候,会根据 < 操作符比较元素大小并判断元素是否相同, 并选择合适的位置插入到容器中。当对这个容器中的元素进行遍历时,输出结果会按照 < 操作符的顺序来逐个遍历。

而无序容器中的元素是不进行排序的,内部通过哈希表实现,插入和搜索元素的平均复杂度为 O(constant) , 在不关心容器内部元素顺序时,能够获得显著的性能提升。

C++11 引入了两组无序容器: std::unordered_map / std::unordered_multimapstd::unordered_set / std::unordered_multiset

它们的用法和原有的 std::map/std::multimap/std::set/set::multiset 基本类似, 由于这些容器我们已经很熟悉了,便不再举例了。

9. Queue / PriorityQueue

methods:

  • push()
  • pop()
  • front()
  • empty()
  • size()

A priority queue is a container that provides constant time extraction of the largest element.

In a priority queue, an element with high priority is served before an element with low priority.

All insertion / deletion operations takes place in Logarithmic time.

10. 10. Stack

methods:

  • push()
  • pop()
  • top() # Returns a reference to the top most element of the stack
  • empty()
  • size()

11. 11. Bitsets

https://github.com/kjsce-codecell/standard-library-in-x/blob/master/cpp/containers/bitsets.md

12. 12. std::array

看到这个容器的时候肯定会出现这样的问题:

  • 为什么要引入 std::array 而不是直接使用 std::vector

    与 std::vector 不同,std::array 对象的大小是固定的,如果容器大小是固定的,那么可以优先考虑使用 std::array 容器。

    另外由于 std::vector 是自动扩容的,当存入大量的数据后,并且对容器进行了删除操作, 容器并不会自动归还被删除元素相应的内存,这时候就需要手动运行 shrink_to_fit() 释放这部分内存。

  • 已经有了传统数组,为什么要用 std::array

    使用 std::array 能够让代码变得更加“现代化”,而且封装了一些操作函数,比如获取数组大小以及检查是否非空,同时还能够友好的使用标准库中的容器算法,比如 std::sort。

12.1. 12.1. std::array 的使用

std::array<int, 4> arr = {1, 2, 3, 4};

arr.empty(); // 检查容器是否为空
arr.size(); // 返回容纳的元素数 // 迭代器支持
for (auto &i : arr)
{
// ...
} // 用 lambda 表达式排序
std::sort(arr.begin(), arr.end(), [](int a, int b) {
return b < a;
}); // 数组大小参数必须是常量表达式
constexpr int len = 4;
std::array<int, len> arr = {1, 2, 3, 4}; // 非法,不同于 C 风格数组,std::array 不会自动退化成 T*
// int *arr_p = arr;

12.2. 12.2. 兼容 C 风格的接口

void foo(int *p, int len) {
return;
} std::array<int, 4> arr = {1,2,3,4}; // C 风格接口传参
// foo(arr, arr.size()); // 非法, 无法隐式转换
foo(&arr[0], arr.size());
foo(arr.data(), arr.size()); // 使用 `std::sort`
std::sort(arr.begin(), arr.end());

STL容器操作的更多相关文章

  1. STL容器能力一览表和各个容器操作函数异常保证

    STL容器能力一览表 Vector Deque List Set Multiset map Multimap 典型内部 结构 dynamic array Array of arrays Doubly ...

  2. 【C++】STL,vector容器操作

    C++内置的数组支持容器的机制,但是它不支持容器抽象的语义.要解决此问题我们自己实现这样的类.在标准C++中,用容器向量(vector)实现.容器向量也是一个类模板.标准库vector类型使用需要的头 ...

  3. c++ stl容器set成员函数介绍及set集合插入,遍历等用法举例

    c++ stl集合set介绍 c++ stl集合(Set)是一种包含已排序对象的关联容器.set/multiset会根据待定的排序准则,自动将元素排序.两者不同在于前者不允许元素重复,而后者允许. 1 ...

  4. STL容器删除元素的陷阱

    今天看Scott Meyers大师的stl的用法,看到了我前段时间犯的一个错误,发现我写的代码和他提到错误代码几乎一模一样,有关stl容器删除元素的问题,错误的代码如下:std::vector< ...

  5. STL容器的适用情况

     转自http://hsw625728.blog.163.com/blog/static/3957072820091116114655254/ ly; mso-default-props:yes; m ...

  6. STL容器的遍历删除

    STL容器的遍历删除 今天在对截包程序的HashTable中加入计时机制时,碰到这个问题.对hash_map中的每个项加入时间后,用查询函数遍历hash_map,以删除掉那些在表存留时间比某个阈值长的 ...

  7. STL容器与配接器

    STL容器包括顺序容器.关联容器.无序关联容器 STL配接器包括容器配接器.函数配接器 顺序容器: vector                             行为类似于数组,但可以根据要求 ...

  8. STL容器的本质

    http://blog.sina.com.cn/s/blog_4d3a41f40100eof0.html 最近在学习unordered_map里面的散列函数和相等函数怎么写.学习过程中看到了一个好帖子 ...

  9. STL容器是否是线程安全的

    转载http://blog.csdn.net/zdl1016/article/details/5941330 STL的线程安全. 说一些关于stl容器的线程安全相关的话题. 一般说来,stl对于多线程 ...

随机推荐

  1. Alink漫谈(四) : 模型的来龙去脉

    Alink漫谈(四) : 模型的来龙去脉 目录 Alink漫谈(四) : 模型的来龙去脉 0x00 摘要 0x01 模型 1.1 模型包含内容 1.2 Alink的模型文件 0x02 流程图 0x03 ...

  2. 用开源软件TrinityCore在Debian 10上搭建魔兽世界8.3.0.34220的服务器

    用开源软件TrinityCore在Debian 10上搭建魔兽世界8.3.0.34220的服务器 TrinityCore是魔兽世界(World of Warcraft)的开源的服务端.目前支持魔兽的3 ...

  3. 实验五:shell脚本编程

    项目 内容 这个作业属于哪个课程 班级课程的主页链接 这个作业的要求在哪里 作业要求链接地址 学号-姓名 17043133-木腾飞 作业学习目标 1.了解shell 脚本的概念及应用2.掌握shell ...

  4. python - 怎样使用 requests 模块发送http请求

    最近在学python自动化,怎样用python发起一个http请求呢? 通过了解 request 模块可以帮助我们发起http请求 步骤: 1.首先import 下 request 模块 2.然后看请 ...

  5. 微信小程序订阅

    微信小程序订阅 摘要 1.基于promise封装微信小程序订阅 2.解决由于微信基础库版本低下的兼容 3.解决“总是保持以上选择,不再询问”的取消状态 主要运用API: requestSubscrib ...

  6. Android_存储访问框架SAF

    概念 存储访问框架---Storage Access Framework (SAF),这是在Android4.4(API level 19)之后引入的. 借助 SAF,用户可轻松在其所有首选文档存储提 ...

  7. 【C++】常量

    注意:以下内容摘自文献[1],修改了部分内容. 1.常量:常量的值是不能改变的,一般从其字面形式即可判别是否为常量. 2.常量包括数值型常量(即常数)和字符型常量. 3.常量无unsigned型.但一 ...

  8. python 05—字典

    一.字典的键是唯一的 键:简单对象,例[字符串.整数.浮点数.bool值] list不能作为键,但可以作为值. 例: score = { '萧峰' : 95, '段誉' : 97, '虚竹' : 89 ...

  9. 从软件开发到 AI 领域工程师:模型训练篇

    前言 4 月热播的韩剧<王国>,不知道大家有没有看?我一集不落地看完了.王子元子出生时,正逢宫内僵尸作乱,元子也被咬了一口,但是由于大脑神经元尚未形成,寄生虫无法控制神经元,所以医女在做了 ...

  10. Java实现 LeetCode 825 适龄的朋友(暴力)

    825. 适龄的朋友 人们会互相发送好友请求,现在给定一个包含有他们年龄的数组,ages[i] 表示第 i 个人的年龄. 当满足以下条件时,A 不能给 B(A.B不为同一人)发送好友请求: age[B ...