1.作用 / 与优先队列的区别
(1)插入一个元素,自动排序,保证其内部元素有序(升序)。优先队列也可以做到这一点。
(2)支持任意增删一个元素,而优先队列做不到这一点,这是两者其中一个区别。
(3)使用set的前提是唯一键值对,保证了其内部没有重复元素,而优先队列内部同一元素可以有多个,这是两者第二个区别。
2.常用操作
set<int> se; //以int型为例 默认按键值升序
set<int,greater<int>> se; //降序排列
int x;
q.insert(x); //插入元素x,若x已存在,则什么都不干
q.find(x); //在q中查找x,返回x的迭代器,若x不存在,则返回指向q尾部的迭代器即 q.end()
q.erase(x); //删除元素x,若x不存在,则什么都不干
q.erase(it) //删除集合中地址为it的元素
q.clear(); //清空集合
q.size(); //返回集合se中元素的个数
q.empty(); //判断se是否为空,若是返回1,否则返回0
q.lower_bound(x); //返回一个迭代器,指向第一个键值不小于x的元素,若这个数不存在,则返回se.end()
q.upper_bound(x); //返回一个迭代器,指向第一个键值大于x的元素,若这个数不存在,则返回se.end()
q.begin(); //返回指向se中第一个元素的迭代器
q.end(); //返回指向se最后一个元素下一个位置的迭代器 ( 这是一个空指针 ),这个方法很少直接使用,一般是配合其他操作判断某个元素是否存在
3.核心代码片段分析
else //若是删除操作,且集合不为空
{
set<int> :: iterator it = se.lower_bound(len),bf=it;
//也可写成
set<int> :: iterator it,bf;
it = se.lower_bound(len);
bf=it;
if (bf!=se.begin())
bf--;
//若*it不是第一个元素,则bf(before)表示前一个元素
//不能写成bf=it-1,bf和it都是指针类型
if (it!=se.end() && len-(*bf)>(*it)-len)
bf=it;
//举个例子,集合中元素是1 3 5 7,查找的是 9,根据定义“q.lower_bound(x); //返回一个迭代器,
指向第一个键值不小于x的元素,若这个数不存在,则返回se.end()”,因为不存在,所以返回的是se.end(),
就是7后面的那个空指针,这时不能够对it解引用。
cout<<*bf<<endl;
se.erase(*bf);
//最终输出的是*bf
//千万别忘删除这个元素
#使用lower_bound和upper_bound要注意特判首尾
4.完整代码
#include<iostream>
#include<algorithm>
#include<set>
using namespace std;
int n,opt,len,w1,w2;
set<int> se;
int main()
{
int i;
cin>>n;
while (n--)
{
cin>>opt>>len;
if (opt==1)
{
if (se.find(len)!=se.end())
cout<<"Already Exist"<<endl;
else
se.insert(len);
}
else
{
if (se.empty())
cout<<"Empty"<<endl;
else
{
set<int> :: iterator it = se.lower_bound(len),bf=it;
if (bf!=se.begin())
bf--;
if (it!=se.end() && len-(*bf)>(*it)-len)
bf=it;
cout<<*bf<<endl;
se.erase(*bf);
}
}
}
return 0;
}
标签:bf,set,洛谷,STL,元素,bound,len,end,se
From: https://blog.csdn.net/2301_81608637/article/details/136586466