[TOC]
c++ STL
容器
序列容器
vector
array
queue
deque
list
forward_list
关联容器
map
set
unordered_map
multimap
unordered_multimap
multiset
unordered_multiset
1. vector
初始化
1 | vector<int> vec1; |
push_back()
insert()
size()
1 |
|
Delete ~ ~Erase()
erase
返回一个迭代器,指向被删除元素之后的位置。- 如果尝试删除超出向量范围的索引,
erase
将抛出std::out_of_range
异常。 - 在删除元素后,所有后续元素的索引都会减少。例如,如果你删除了索引为2的元素,索引为3的元素会变成索引为2的元素。
erase
会释放被删除元素占用的内存。- 使用
erase
后,向量的长度会减少。
1 | std::vector<int> vec = {1, 2, 3, 4, 5}; |
find
1 | //# find |
replace
1 | std::vector<int> vec = {1, 2, 3, 4, 5}; |
find + delete (删除找到的第一个元素)
1 | vector<int> vec = {3, 4, 5, 6, 7, 4}; |
find + replace
1 | std::vector<int> vec = {1, 2, 3, 4, 5}; |
max
1 | vector<int> a = { 2,4,6,7,1,0,8,9,6,3,2 }; |
vector TO 数组
1:memcpy
1 | // 1 vector to arr |
ref baidu wenku
2: std::copy vector to arr
1 | vector<int> input({1,2,3,4,5}); |
ref:: https://www.techiedelight.com/convert-vector-to-array-cpp/
max
1 | vector<int> a = { 2,4,6,7,1,0,8,9,6,3,2 }; |
vector 切片
1 | // 方法1 |
去重
1 | // 1 |
1 |
2. Map
存放的元素都是K-V键值对,并且Key是不能重复的。
构造函数
1 | map<int, string> mapStudent; |
插入数据
1 | mapStudent.insert(pair<int, string>(1, "student_one")); //pair<>()函数 |
查找
1 | iter = mapStudent.find(1); // find(key) |
遍历
1 | map<int, CString> maps; // 或者map < int, 结构体名> maps; |
删除与清空元素
1 | // 迭代器删除 |
大小
1 | int mSize = mapStudent.size(); |
原文链接:https://blog.csdn.net/bandaoyu/article/details/87775533
3. unordered_map
存放的元素都是K-V键值对,并且Key是不能重复的。
1 |
|
建立Hashmap
1 | unordered_map<int,int> Hashmap; |
遍历Map
1 | //第一种 |
辨析.map VS unordered_map
内部实现机理不同
map: map内部实现了⼀个红⿊树(红⿊树是⾮严格平衡⼆叉搜索树,⽽AVL是严格平衡⼆叉搜索树),红⿊树具有⾃动排序的功能,因此map内部的所有元素都是有序的,红⿊树的每⼀个节点都代表着map的⼀个元素。因此,对于map进⾏的查找,删除,添加等⼀系列的操作都相当于是对红⿊树进⾏的操作。map中的元素是按照⼆叉搜索树(⼜名⼆叉查找树、⼆叉排序树,特点就是左⼦树上所有节点的键值都⼩于根节点的键值,右⼦树所有节点的键值都⼤于根节点的键值)存储的,使⽤中序遍历可将键值按照从⼩到⼤遍历出来。
unordered_map: 内部实现了⼀个哈希表(也叫散列表,通过把关键码值映射到Hash表中⼀个位置来访问记录,查找的时间复杂度可达到O(1),其在海量数据处理中有着⼴泛应⽤)。因此,其元素的排列顺序是⽆序的。
map
特点 | ||
---|---|---|
map | 有序性,这是map结构最⼤的优点,其元素的有序性在很多应⽤中都会简化很多的操作 红⿊树,内部实现⼀个红⿊书使得map的很多操作在lgn的时间复杂度下就可以实现,因此效率⾮常的⾼ 缺点: 空间占⽤率⾼,因为map内部实现了红⿊树,虽然提⾼了运⾏效率,但是因为每⼀个节点都需要额外保存⽗节点、孩⼦节点和红/⿊ 性质,使得每⼀个节点都占⽤⼤量的空间 适⽤处:对于那些有顺序要求的问题,⽤map会更⾼效⼀些 |
|
unorder_map | 优点: 因为内部实现了哈希表,因此其查找速度⾮常的快 缺点: 哈希表的建⽴⽐较耗费时间 适⽤处:对于查找问题,unordered_map会更加⾼效⼀些,因此遇到查找问题,常会考虑⼀下⽤unordered_map |
|
总结:
内存占有率的问题就转化成红⿊树 VS hash表 , 还是unorder_map占⽤的内存要⾼。
- 但是unordered_map执⾏效率要⽐map⾼很多
- 对于unordered_map或unordered_set容器,其遍历顺序与创建该容器时输⼊的顺序不⼀定相同,因为遍历是按照哈希表从前往后依次遍历的
map和unordered_map的使⽤
- unordered_map的⽤法和map是⼀样的,提供了 insert,size,count等操作,并且⾥⾯的元素也是以pair类型来存贮的。
- 其底层实现是完全不同的,上⽅已经解释了,但是就外部使⽤来说却是⼀致的。
4. set
1 | // init |
https://shengyu7697.github.io/std-set/
排列组合
全排列(stl)
从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。如果这组数有n个,那么全排列数为n!个。
比如a,b,c的全排列一共有3!= 6 种 分别是{a, b, c}、{a, c, b}、{b, a, c}、{b, c, a}、{c, a, b}、{c, b, a}。
api:
prev_permutation
next_permutation
1 |
|
全排列递归思路
我们可以将这个排列问题画成图形表示,即排列枚举树,比如下图为{1,2,3}的排列枚举树,此树和我们这里介绍的算法完全一致;
算法思路:
(1)n个元素的全排列=(n-1个元素的全排列)+(另一个元素作为前缀);
(2)出口:如果只有一个元素的全排列,则说明已经排完,则输出数组;
(3)不断将每个元素放作第一个元素,然后将这个元素作为前缀,并将其余元素继续全排列,等到出口,出口出去后还需要还原数组;
排列(递归)
1 | /** permutaion: 排列。 |
组合(数组)
1 |
|
组合(stl, vector)
1 |
|
组合(class,递归)
1 |
|
可重复组合(运行Pass)
允许元素重复的一类组合问题
用P(n, k)表示从n个元素中选出k个元素(允许重复)的组合问题,那么此问题可以分解为两个子问题:P(n, k-1)和P(n-1, k),
解释如下:
P(n, k)中n个元素的所有k元素组合可以分成两部分。
第一部分的每个组合均以第一个元素开始,再连接上k-1个元素的组合,即再连接上P(n,k-1)的每一个组合;
第二部分的每个组合不含有第一个元素,即P(n-1, k)中的每一个组合(此时元素为后n-1个元素)。
因此,P(n, k)分解为P(n, k-1)和P(n-1, k)。
如果用f(n, k)表示P(n, k)中的组合数,那么有:
(1)当k = 1时,f(n, k) = n
(2)当n = 1时,f(n, k) = 1
(3)当k > 1且n > 1时,f(n, k) = f(n, k -1) + f(n-1, k)
此外,有公式f(n, k) = C(n + k -1, k)(表示n+k-1选k的组合数,没有重复元素),这可以用归纳法证明,这里就不啰嗦了。
1 | template <typename ElemType> |