stl set 与multiset的使用
c++ stl集合(Set)是一种包含已排序对象的关联容器。set/multiset会根据待定的排序准则,自动将元素排序。两者不同在于前者不允许元素重复,而后者允许。
1) 不能直接改变元素值,因为那样会打乱原本正确的顺序,要改变元素值必须先删除旧元素,则插入新元素。
2) 不提供直接存取元素的任何操作函数,只能通过迭代器进行间接存取,而且从迭代器角度来看,元素值是常数。
3) 元素比较动作只能用于型别相同的容器(即元素和排序准则必须相同)
C++ STL 中的 set 容器类模板中未提供 at() 成员函数,也未对 [] 运算符进行重载。因此,要想访问 set 容器中存储的元素,只能借助 set 容器的迭代器。
值得一提的是,C++ STL 标准库为 set 容器配置的迭代器类型为双向迭代器。这意味着,假设 p 为此类型的迭代器,则其只能进行 ++p、p++、--p、p--、*p 操作,并且 2 个双向迭代器之间做比较,也只能使用 == 或者 != 运算符。
头文件
#include<set>
定义
set<int> s;
c++ set的常用方法
begin(),返回set容器的第一个元素,类型为迭代器
end(),返回set容器的最后一个元素,类型为迭代器
clear() ,删除set容器中的所有的元素
empty(),判断set容器是否为空
max_size(),返回set容器可能包含的元素最大个数
size() ,返回当前set容器中的元素个数
rbegin() ,返回的值和end()相同,类型为迭代器
rend() ,返回的值和rbegin()相同,类型为迭代器
count(key_val),用来查找set中某个某个键值出现的次数。这个函数在set并不是很实用,因为一个键值在set只可能出现0或1次,这样就变成了判断某一键值是否在set出现过了。
equal_range(),返回一对定位器,分别表示第一个大于或等于给定关键值的元素和 第一个大于给定关键值的元素,这个返回值是一个pair类型,如果这一对定位器中哪个返回失败,就会等于end()的值。
erase(iterator) ,删除定位器iterator指向的值。
erase(first,second),删除定位器first和second之间的值。
erase(key_value),删除键值key_value的值。
小结:set中的删除操作是不进行任何的错误检查的,比如定位器的是否合法等等,所以用的时候自己一定要注意。
find(key_val),返回给定值值得定位器,如果没找到则返回end(),类型为迭代器。
insert(key_value), 将key_value插入到set中 ,返回值是pair<set<int>::iterator,bool>,bool标志着插入是否成功,而iterator代表插入的位置,若key_value已经在set中,则iterator表示的key_value在set中的位置。
inset(first,second),将定位器first到second之间的元素插入到set中,返回值是void.
lower_bound(key_value),返回第一个大于等于key_value的定位器,类型为迭代器
upper_bound(key_value),返回第一个大于key_value的定位器,类型为迭代器
实例
#include<bits/stdc++.h>
using namespace std;
int main()
{
set<int> s;
s.insert(89);
s.insert(9);
s.insert(89);
s.insert(78);
set<int>::iterator it;
//s的insert()会自动排序,并不能有相同值的元素
for (it=s.begin();it!=s.end();it++)
{
cout<<*it<<" ";
}
cout<<endl;
cout<<(s.find(9)==s.end())<<endl;//输出为0表示查找成功
cout<<(s.find(19)==s.end())<<endl;//输出为1表示查找失败
cout<<s.count(9)<<endl;//输出1表示有一个9
cout<<s.count(19)<<endl; //输出0表示没有19
cout<<(*s.lower_bound(9))<<endl; //输出9表示大于等于9的第一个数是9
cout<<(*s.lower_bound(19))<<endl;//输出78表示大于等于19的第一个数是78
cout<<(*s.upper_bound(9))<<endl; //输出78表示大于9的第一个数是78
cout<<(*s.upper_bound(19))<<endl;//输出78表示大于19的第一个数是78
s.erase(19);
for (it=s.begin();it!=s.end();it++)
{
cout<<*it<<" ";
}
cout<<endl;
s.erase(9);
for (it=s.begin();it!=s.end();it++)
{
cout<<*it<<" ";
}
cout<<endl;
return 0;
}
set迭代器的使用实现
#include<set>
#include<iostream>
using namespace std;
set<int> s;
int main()
{
int n;
cin>>n;
for (int i=1;i<=n;i++)
{
int x;
cin>>x;
s.insert(x);
}
set<int>::iterator it;//正向迭代器是双向的
for (it=s.begin();it!=s.end();it++)
{
cout<<*it<<" ";
}
cout<<endl;
for (it=s.end(),it--;;it--)
{
cout<<*it<<" ";
if(it==s.begin()) break;
}
cout<<endl;
set<int>::reverse_iterator rit;//反向迭代器是双向的
for (rit=s.rbegin();rit!=s.rend();rit++)
{
cout<<*rit<<" ";
}
cout<<endl;
for (rit=s.rend(),rit--;;rit--)
{
cout<<*rit<<" ";
if (rit==s.rbegin()) break;
}
cout<<endl;
}
实例三
#include<bits/stdc++.h>
using namespace std;
int main()
{
set<int,greater<int> > s;
int n;
cin>>n;
for (int i=1;i<=n;i++)
{
int x;
cin>>x;
s.insert(x);
}
set<int,greater<int> >::iterator it;
for (it=s.begin();it!=s.end();it++)
{
cout<<*it<<" ";
}
return 0;
}
练习题
1、排序,去重
2、 P1090 [NOIP2004 提高组] 合并果子 / [USACO06NOV] Fence Repair G
3、 P1886 滑动窗口 /【模板】单调队列
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!