4.集合set
集合set可以提供对数时间的插入、删除、查找的集合数据结构。底层原理是红黑树。
使用时加#include<set>
集合三要素 | 解释 | set | multiset | unordered_set |
---|---|---|---|---|
确定性 | 一个元素要么在集合中,要么不在 | ✔ | ✔ | ✔ |
互异性 | 一个元素仅可以在集合中出现一次 | ✔ | ❌(任意次) | ✔ |
无序性 | 集合中的元素是没有顺序的 | ❌(从小到大) | ❌(从小到大) | ✔ |
4.1常用方法
4.1.1构造
set<数据类型,比较器> 名称
- 比较器:比较大小使用的比较器,默认为
less<类型>
,也可使用自定义比较器
举例:
set<int> stl; //储存int的集合(从小到大)
set<int, greater<int>> stl2; //储存int的集合(从大到小)
4.1.2遍历
可使用迭代器进行遍历:
for (set<int>::iterator it = st.begin(); it != st.end(); ++it)
cout << *it << endl;
基于范围的循环(C++ 11):
for (auto &ele : st)
cout << ele << endl;
4.1.3插入、删除等
作用 | 用法 | 示例 |
---|---|---|
插入元素 | .insert(元素) | st.insert(1); |
删除元素 | .erase(元素) | st.erase(2); |
查找元素 | .find(元素) | auto it = st.find(1); |
判断元素是否存在 | .count(元素) | st.count(3); |
查看大小 | .size | st.size() |
清空 | .clear | st.clear() |
判空 | .empty | st.empty() |
4.2注意事项
set虽然可以遍历,但是只可以使用迭代器进行遍历,它没有下表这个概念,无法通过下标进行数据的访问。
错误用法:
cout << st[0] << endl;
set的迭代器的元素是只读的,(因为是const迭代器),不可修改其值,修改的话必须删除再插入
错误用法:
*st.begin() = 1;
不可用迭代器计算下标
set 的迭代器不能像 vector 一样相减得到下标。下面是错误用法:
auto it = st.find(2); // 正确,返回2所在位置的迭代器。
int idx = it - st.begin(); // 错误!不可相减得到下标。
5.映射
映射可以提供对数时间的有序键值对结构。底层原理是红黑树
#include<map>
映射:
1
→
5
2
→
6
3
→
7
4
→
8
⋮
\begin{matrix} 1&\to&5\\ 2&\to&6\\ 3&\to&7\\ 4&\to&8\\ &\vdots \end{matrix}
1234→→→→⋮5678
性质 | 解释 | map | multimap | unordered_map |
---|---|---|---|---|
互异性 | 一个键仅可以在映射中出现一次 | ✔ | ❌(任意次) | ✔ |
无序性 | 键是没有顺序的 | ❌(从小到大) | ❌(从小到大) | ✔ |
5.1常用方法
5.1.1构造
map<键类型, 值类型, 比较器> mp
- 键类型:要储存键的数据类型
- 值类型:要储存值的数据类型
- 比较器:键比较大小使用的比较器,默认为
less<类型>
,可自定义
5.1.2遍历
可使用迭代器进行遍历:
for (map<int, int>::iterator it = mp.begin(); it != mp.end(); ++it)
cout << it->first << ' ' << it->second << endl;
基于范围的循环:
for (auto &pr : mp)
cout << pr.first << ' ' << pr.second << endl;
5.1.3其他
作用 | 用法 | 示例 |
---|---|---|
增 / 改 / 查元素 | 中括号 | mp[1] = 2; |
查元素(返回迭代器) | .find(元素) | auto it = mp.find(1); |
删除元素 | .erase(元素) | mp.erase(2); |
判断元素是否存在 | .count(元素) | mp.count(3); |
查看大小 | .size | mp.size() |
清空 | .clear | mp.clear() |
判空 | .empty | mp.empty() |
5.2适用情况
需要维护映射的场景可以使用:输入若干字符串,统计每种字符串的出现次数。(map<string, int> mp
)
5.3注意事项
中括号访问时默认值
如果使用中括号访问 map 时对应的键不存在,那么会新增这个键,并且值为默认值,因此中括号会影响键的存在性。
map<char, int> mp;
cout << mp.count('a') << endl; // 0
mp['a']; // 即使什么都没做,此时mp['a']=0已经插入了
cout << mp.count('a') << endl; // 1
cout << mp['a'] << endl; // 0
不可用迭代器计算下标
map 的迭代器不能像 vector 一样相减得到下标。下面是错误用法:
auto it = mp.find('a'); // 正确,返回2所在位置的迭代器。
int idx = it - mp.begin(); // 错误!不可相减得到下标。