本文内容选自 OI-wiki。
此处只是对其进行整理。
Set
部分内容选自 csdn。
定义: set <T>st;
1、特点
set 作为一个集合,主要具有下述特点:
-
元素都是有序的
-
没有重复的元素
-
拥有对数复杂度
2、set 插入与删除操作
-
insert(x)
容器中没有等价元素时,将元素 x 插入 set 中。insert 函数的返回值为pair<iterator, bool>
,其中 iterator 是一个指向所插入元素(或指向等于所插入值的原本就在容器中的元素)的迭代器;bool 则代表元素是否插入成功。 -
erase(x)
删除值为 x 的所有元素,返回删除元素的个数。 -
clear()
清空 set。 -
erase(pos)
删除迭代器为 pos 的元素,要求元素必须合法。 -
erase(first, last)
删除迭代器在(first, last)
范围内的所有元素。
3、 set 迭代器
此处只介绍两种最常用的:
-
begin()
返回指向首元素的迭代器。 -
end()
返回指向尾元素的下一个位置的迭代器。
4、 查找操作
-
count(x)
返回 set 内键为 x 的元素数量 -
find(x)
在 set 内存在键为 x 的元素时会返回该元素的迭代器,否则返回 end() -
lower_bound(x)
返回指向首个不小于给定键的元素的迭代器,否则返回 end() -
upper_bound(x)
返回指向首个大于给定键的元素的迭代器,否则返回 end()
PS. set 自带的 lower_bound()
和 upper_bound()
的查找复杂度为 O(log n)O(log n) 而 algorithm 库中的为 O(n)。
-
size()
返回 set 中元素个数 -
empty()
判断 set 是否为空。
拓展:set 不提供 nth_element()
,只能使用 algorithm 中的函数,时间复杂度为 O(n)
5、 set 与结构体结合
当 set 集合中的元素为结构体时,该结构体必须实现算数运算符 < 的重载。代码如下:
6、【使用样例】set 在贪心中的应用
例:找出并删除最小的大于等于某个值的元素。
#include<set>
using namespace std;
struct Node{
//其他定义
//运算符重载
bool operator <(const Node P) const{ return var<P.var; }//排序规则
};
set<Node>st; //定义含结构体的 set
int main(){
//其他
st.insert((Node){...}); //插入结构体
//程序正文
return 0;
}
Map
定义:map <key, T>mp;
1. 特点
-
键和值相对应。
-
元素都是有序且唯一的,不能存在键相同的元素。
-
拥有对数复杂度。
2.操作
大部分操作同 set,此处补充其他操作。
-
可以直接通过下标访问进行查询或插入操作。
-
insert(pair<Key, T>())
插入类型为 pair 的元素。
PS. 不同之处:若往 map 内键重复的元素,使用下标会覆盖以前的值,而使用 insert 会失败。
-
count(x)
返回容器内键为 x 的元素数量。 -
find(x)
若容器内存在键为 x 的元素,返回该元素迭代器。否则返回end()
。
PS. 对 map 的迭代器解引用后,得到的类型是 pair<Key, T>
3. 【使用样例】map 存储复杂状态
此时,键是状态,值是与之相关的答案。
// 存储状态与对应的答案
map<string, int> mp;
// 新搜索到的状态与对应答案
string status;
int ans;
// 查找对应的状态是否出现过
map<string, int>::iterator it = mp.find(status);
if (it == mp.end()) {
// 尚未搜索过该状态,将其加入状态记录中
mp[status] = ans;
// 进行相应操作……
} else {
// 已经搜索过该状态,进行相应操作……
}