除了没有单独的键,set 容器和 map 容器很相似。
定义 set 容器的模板如下四种:
定义 set 的模板有 4 种,其中两种默认使用 less
从有序和无序关联容器获取的各种迭代器之间有一些区别。我们可以从有序容器得到正向和反向迭代器,但是只能从无序容器得到正向迭代器。
一般来说,当 set 中有大量元素时,在无序 set 上执行的随机插入和检索操作要比有序 set 快。在有 n 个元素的有序 set 中检索元素的时间复杂度是 logn。在无序 set 中检索元素的平均时间复杂度是常量O(1),这和元素的个数无关,尽管实际性能会受元素哈希操作和内部组织效率的影响。
s.begin() 返回set容器的第一个元素
s.end() 返回set容器的最后一个元素
s.clear() 删除set容器中的所有的元素
s.empty() 判断set容器是否为空
s.insert() 插入一个元素
s.erase(it) 删除一个元素
s.size() 返回当前set容器中的元素个数
equal_range():返回一对定位器,分别表示第一个大于或等于给定关键值的元素和 第一个大于给定关键值的元素,这个返回值是一个pair类型,如果这一对定位器中哪个返回失败,就会等于end()的值.
还有两个功能类似的函数:count()和find()
1.count() :用来查找set中某个元素出现的次数。这个函数在set并不是很实用,因为一个键值在set只可能出现0或1次,这样就变成了判断某一键值是否在set出现过了。
2.find(): 用来查找set中某个元素出现的位置。如果找到,就返回这个元素的迭代器,如果这个元素不存在,则返回 s.end() 。 (最后一个元素的下一个位置,s为set的变量名)
#include
#include
#include
using namespace std;
set s;
int main(){
set setA; //默认是小于比较器less的set
set > setB; //创建一个带大于比较器的set,需包含头文件functional
int a[5] = {1,2,3,4,5};
set setC(a,a+5); //数组a初始化一个set;
set setD(setC.begin(),setC.end()); //setc初始化一个set
//上述两例均为区间初始化
set setE(setD); //拷贝构造创建set
return 0;
}
int main(){
int cnt = 1;
s.insert(1);
s.insert(2);
s.insert(5);
setprint(cnt++);
s.insert(2); //set只允许用一个值出现一次,要插入相同元素请用multiset
setprint(cnt++);
int a[4] = {11,12,13,14};
s.insert(a,a+4); //将区间[a, a+4]里的元素插入容器
setprint(cnt++);
return 0;
}
set.erase(n) 删除元素n
set.clear() 删除set容器中的所有的元素
int main(){
int cnt = 1;
for(int i = 1; i < 11; i++){
s.insert(i);
}
s.erase(9); //根据元素删除
setprint(cnt++);
set::iterator ita = s.begin();
set::iterator itb = s.begin();
s.erase(ita); //删除迭代器指向位置的元素
ita = s.begin();
itb = s.begin();
itb++;itb++;
s.erase(ita,itb); //删除区间[ita,itb)的元素
s.clear();
return 0;
}
不能直接修改容器内数据,所以只能删除某元素再插入要修改的数值。
所有 set
set.find() 查找一个元素,如果容器中不存在该元素,返回值等于set.end()
#include
#include
using namespace std;
sets;
int main(){
int cnt = 1;
s.insert(1);
s.insert(2);
s.insert(5);
setprint(cnt++);
if(s.find(2) != s.end())
cout << "2 is existent" << endl;
else
cout << "2 is non-existent" << endl;
return 0;
}
for (set::iterator it = s.begin(); it != s.end(); ++it)
{
cout << *it << endl;
}
s.lower_bound() 返回第一个大于或等于给定关键值的元素
s.upper_bound() 返回第一个大于给定关键值的元素
s.equal_range() 返回一对定位器,分别表示 第一个大于或等于给定关键值的元素 和 第一个大于给定关键值的元素,这个返回值是一个pair类型,如果这一对定位器中哪个返回失败,就会等于s.end()
#include
#include
using namespace std;
int main(){
set s;
s.insert(1);
s.insert(2);
s.insert(5);
cout << "lower_bound & upper_bound test:" << endl;
cout << "第一个大于或等于3的元素: " << *s.lower_bound(3) << endl;
cout << "第一个大于或等于2的元素: " <<*s.lower_bound(2) << endl;
cout << "第一个大于2的元素: " <<*s.upper_bound(2) << endl;
cout << "equal_range test:" << endl;
cout << "第一个大于或等于2的元素: " << *s.equal_range(2).first << endl;
cout << "第一个大于2的元素: " << *s.equal_range(2).second << endl;
return 0;
}
#include
#include
#include
using namespace std;
struct Info
{
string name;
double score;
bool operator < (const Info &a) const // 重载“<”操作符,自定义排序规则
{
//按score由大到小排序。如果要由小到大排序,使用“>”即可。
return a.score < score;
}
};
int main()
{
set s;
Info info;
//插入三个元素
info.name = "Jack";
info.score = 80;
s.insert(info);
info.name = "Tom";
info.score = 99;
s.insert(info);
info.name = "Steaven";
info.score = 60;
s.insert(info);
set::iterator it;
for(it = s.begin(); it != s.end(); it++)
cout << (*it).name << " : " << (*it).score << endl;
return 0;
}
/*
运行结果:
Tom : 99
Jack : 80
Steaven : 60
*/
#include
#include
#include
using namespace std;
struct cmp{
bool operator () (const int &a, const int &b){
return a > b;
}
};
sets; //自定义排序函数构造set
void setprint(int cnt){
cout << "Test output :" << cnt << ":" << endl;
for(set::iterator it = s.begin(); it!= s.end(); it++)
cout << *it << " ";
puts("");
return ;
}
int main(){
s.insert(1);
s.insert(2);
s.insert(6);
setprint(1);
return 0;
}
//结果
6 2 1