STL容器操作
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_multimap 和 std::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容器操作的更多相关文章
- STL容器能力一览表和各个容器操作函数异常保证
STL容器能力一览表 Vector Deque List Set Multiset map Multimap 典型内部 结构 dynamic array Array of arrays Doubly ...
- 【C++】STL,vector容器操作
C++内置的数组支持容器的机制,但是它不支持容器抽象的语义.要解决此问题我们自己实现这样的类.在标准C++中,用容器向量(vector)实现.容器向量也是一个类模板.标准库vector类型使用需要的头 ...
- c++ stl容器set成员函数介绍及set集合插入,遍历等用法举例
c++ stl集合set介绍 c++ stl集合(Set)是一种包含已排序对象的关联容器.set/multiset会根据待定的排序准则,自动将元素排序.两者不同在于前者不允许元素重复,而后者允许. 1 ...
- STL容器删除元素的陷阱
今天看Scott Meyers大师的stl的用法,看到了我前段时间犯的一个错误,发现我写的代码和他提到错误代码几乎一模一样,有关stl容器删除元素的问题,错误的代码如下:std::vector< ...
- STL容器的适用情况
转自http://hsw625728.blog.163.com/blog/static/3957072820091116114655254/ ly; mso-default-props:yes; m ...
- STL容器的遍历删除
STL容器的遍历删除 今天在对截包程序的HashTable中加入计时机制时,碰到这个问题.对hash_map中的每个项加入时间后,用查询函数遍历hash_map,以删除掉那些在表存留时间比某个阈值长的 ...
- STL容器与配接器
STL容器包括顺序容器.关联容器.无序关联容器 STL配接器包括容器配接器.函数配接器 顺序容器: vector 行为类似于数组,但可以根据要求 ...
- STL容器的本质
http://blog.sina.com.cn/s/blog_4d3a41f40100eof0.html 最近在学习unordered_map里面的散列函数和相等函数怎么写.学习过程中看到了一个好帖子 ...
- STL容器是否是线程安全的
转载http://blog.csdn.net/zdl1016/article/details/5941330 STL的线程安全. 说一些关于stl容器的线程安全相关的话题. 一般说来,stl对于多线程 ...
随机推荐
- select 下拉模糊查询
http://ivaynberg.github.io/select2/ https://github.com/ https://github.com/ivaynberg.github.io/selec ...
- 让SpringBoot自动化配置不再神秘
本文若有任何纰漏.错误,还请不吝指出! 注:本文提到的Spring容器或者Bean容器,或者Spring Bean容器,都是指同一个事情,那就是代指BeanFactory.关于BeanFactory, ...
- eclipse——Error exists in required project Proceed with launch?
运行java文件时报错: Error exists in required project Proceed with launch? 报错截图: 问题参生原因:开始Buildpath了一个jar ...
- Linux下搭建mongDB环境
参考: https://blog.csdn.net/qq_35763837/article/details/79654023 https://www.linuxidc.com/Linux/2016-0 ...
- SpringBoot--SpringMVC自动配置
SpringMVC自动配置 1.SpringBoot官方文档对SpringMVC的默认配置: Inclusion of ContentNegotiatingViewResolver and BeanN ...
- 循序渐进VUE+Element 前端应用开发(6)--- 常规Element 界面组件的使用
在我们开发BS页面的时候,往往需要了解常规界面组件的使用,小到最普通的单文本输入框.多文本框.下拉列表,以及按钮.图片展示.弹出对话框.表单处理.条码二维码等等,本篇随笔基于普通表格业务的展示录入的场 ...
- JUC : 并发编程工具类的使用
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.JUC是什么 1.JUC定义 JUC,即java.util.concurrent 在并发编程中使用的 ...
- Java实现 LeetCode 374 猜数字大小 II
375. 猜数字大小 II 我们正在玩一个猜数游戏,游戏规则如下: 我从 1 到 n 之间选择一个数字,你来猜我选了哪个数字. 每次你猜错了,我都会告诉你,我选的数字比你的大了或者小了. 然而,当你猜 ...
- Java实现 蓝桥杯VIP 算法训练 采油区域
算法训练 采油区域 时间限制:2.0s 内存限制:512.0MB 提交此题 查看参考代码 采油区域 Siruseri政府决定将石油资源丰富的Navalur省的土地拍卖给私人承包商以建立油井.被拍卖的整 ...
- Java实现 蓝桥杯VIP 算法提高 促销购物
算法提高 促销购物 时间限制:1.0s 内存限制:256.0MB 问题描述 张超来到了超市购物. 每个物品都有价格,正好赶上商店推出促销方案.就是把许多东西一起买更便宜(保证优惠方案一定比原价便宜). ...