【set 与 multiset】

------ 用法概括

· 实质:对于 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 的个数
部分 大部分 绝大部分 摘抄于《算法进阶》(一本好书)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值