set简介
set一般插入元素时,默认使用关键字类型的<
运算符来比较两个关键字,故一般插入后为升序,但是针对自定义数据结构,如结构体,没有<
运算符,故无法进行比较。针对自定义数据结构或者说自定义set排序规则有如下几种方法:
方法一 重载<
在自定义结构体中重载<
则可以实现默认排序,示例代码如下:
#include<iostream>
#include<set>
using namespace std;
struct Students
{
string id;
int age,height;
Students(string s,int a,int h):id(s),age(a),height(h){}
Students() {}
bool operator <(const Students &s) const {
if(id!=s.id) return id<s.id;
else return age<s.age;
}
};
int main(){
set<Students> se;
se.insert(Students("zhou",12,134));
se.insert(Students("wu",13,42));
se.insert(Students("zheng",34,43));
se.emplace("wang",13,43);
se.emplace("zhou",23,43);
for(auto it=se.begin();it!=se.end();it++){
cout<<it->id<<" "<<it->age<<" "<<it->height<<endl;
}
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
运行结果如下:
方法二 重载()
示例代码如下:
#include<iostream>
#include<set>
using namespace std;
struct Students
{
string id;
int age,height;
Students(string s,int a,int h):id(s),age(a),height(h){}
Students() {}
};
class comp{
public:
bool operator()(const Students &s1,const Students &s2){
if(s1.id!=s2.id) return s1.id<s2.id;
return s1.age<s2.age;
}
};
int main(){
set<Students,comp> se;
se.insert(Students("zhou",12,134));
se.insert(Students("wu",13,42));
se.insert(Students("zheng",34,43));
se.emplace("wang",13,43);
se.emplace("zhou",23,43);
for(auto it=se.begin();it!=se.end();it++){
cout<<it->id<<" "<<it->age<<" "<<it->height<<endl;
}
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
方法三 参考《C++ primer(第五版)》
示例代码如下:
#include<iostream>
#include<set>
using namespace std;
struct Students
{
string id;
int age,height;
Students(string s,int a,int h):id(s),age(a),height(h){}
Students() {}
};
bool cmp(const Students &s1,const Students &s2){
if(s1.id!=s2.id) return s1.id<s2.id;
return s1.age<s2.age;
}
int main(){
set<Students,decltype(cmp)*> se(cmp);
se.insert(Students("zhou",12,134));
se.insert(Students("wu",13,42));
se.insert(Students("zheng",34,43));
se.emplace("wang",13,43);
se.emplace("zhou",23,43);
for(auto it=se.begin();it!=se.end();it++){
cout<<it->id<<" "<<it->age<<" "<<it->height<<endl;
}
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
上述代码中,用decltype
来指出自定义操作的类型。当使用decltype
来获得一个函数指针类型时,必须加上一个*
来指出我们要使用一个给定函数类型的指针。用cmp
来初始化se
对象,这表示当我们向se
中插入元素时,通过调用cmp
来为这些元素排序。可以使用cmp
代替&cmp
作为构造函数的参数,因为当我们使用一个函数的名字时,在需要的情况下会自动转化为一个指针,使用&cmp
效果也是一样的。
insert
和 emplace
的使用
emplace
对应insert
,emplace_back
对应于push_back
;但是insert
和push_back
是直接将对象拷贝至容器当中,而emplace
和emplace_back
是先调用存储对象构造函数,在内存中生成对象,然后拷贝至容器中。