------ 用法概括
· 实质:对于 set 容器,可以理解为 “有序集合”,即 排序+去重
对于 multiset 容器,可以理解为 “有序多重集”,即 排序+不去重
set<int> s; // set与multiset的遍历
multiset<int> ss;
int main() {
int x;
for(int i=1; i<=5; i++) {
scanf("%d",&x);
s.insert(x);
ss.insert(x);
}
set<int>::iterator it; // set的迭代器
for(it=s.begin(); it!=s.end(); it++)
printf("%d ",*it);
puts("");
multiset<int>::iterator its; // multiset的迭代器
for(its=ss.begin(); its!=ss.end(); its++)
printf("%d ",*its);
return 0;
}
输入内容:
9 5 0 5 7
输出结果:
0 5 7 9
0 5 5 7 9
注:set和multiset 不能同 vector 数组一样用 [i] 取值 (0 <= i < n)
· 声明:结构类型也可以自定义结构体
set <结构类型> s;
multiset <结构类型> s;
附:而排序顺序类似 大根堆,内部排序依靠 “<” 运算符,依旧可以重载运算符,详细参考 优先队列重载运算符部分
------指令概括
size/empty/clear/迭代器
- 注意:相对于 vector 的迭代器具有所有指针运算能力,而 set和multiset 的迭代器称为 “双向访问迭代器” ,仅支持 “ ++” 和 “ --” 算术相关操作,其时间复杂度都是 O(log n)。
- 其余均与 vector 类似,详细参考 vector 指令概括
begin/end
- s.begin():返回集合中 最小元素 的迭代器
- s.end():返回集合中最大元素的下一个位置的迭代器,同 vector 类似,属于 “前闭后开” 的形式。因此 --s.end() 指向集合中 最大元素 的迭代器
insert
- s.insert(x):把元素 x 插入到集合 s 中,时间复杂度为 O(log n)
- set:在 set 集合中,若元素已存在,则不会重复插入该元素,对集合状态无影响
find
- s.find(x):在集合 s 中查找等于 x 的元素,并返回指向该元素的 迭代器。若不存在,则返回 s.end()。时间复杂度为 O(log n)
lower_bound/upper_bound
- 这两个函数的用法与 find 类似,但查找方式略有不同,时间复杂度 O(log n)
- s.lower_bound(x):查找 >=x 的元素中最小的一个,并返回指向该元素的迭代器
- s.upper_bound(x):查找 >x 的元素中最小的一个,并返回指向该元素的迭代器
erase
- s.erase(it):设 it 是一个迭代器,则从集合 s 中删除迭代器 it 指向的元素,时间复杂度为 O(log n)
- s.erase(x):设 x 是一个元素,则从集合 s 中删除 所有等于 x 的元素,时间复杂度为 O(k + log n),其中 k 为被删除的元素个数
- 若想从 multiset 中删除至多 1 个等于 x 的元素,可以执行:
if( (it = s.find(x)) != s.end() ) s.erase(it);
count
- s.count(x):返回集合 s 中等于 x 的元素个数,时间复杂度为 O(k + log n),其中 k 为 元素 x 的个数