在set容器中构造的容器默认按照升序排列
#include<set>#include<iostream>using namespace std;int main(){ set<int> st1; st1.insert(1); st1.insert(4); st1.insert(3); st1.insert(8); st1.insert(15); set<int>::iterator it; for(it=st1.begin();it!=st1.end();it++) { cout<<*it<<" "; } cout<<endl; return 0;}
运行结果:
可以通过自带的构造方法实现降序的 set容器:
#include<set>#include<iostream>using namespace std;int main(){ set<int,greater<int>> st1; st1.insert(1); st1.insert(4); st1.insert(3); st1.insert(8); st1.insert(15); set<int>::iterator it; for(it=st1.begin();it!=st1.end();it++) { cout<<*it<<" "; } cout<<endl; return 0;}
运行结果:
那若是需求set容器存储一系列对象,并按照对象的某个成员排序该如何做呢?
这里定义一个学生类,类中包含学生姓名(name),成绩(grade),学号(id),并分布别实现导入学生信息到set容器中后,自动按照成绩降序、升序排列,读者也可以按此方法实现按学号排序。
首先定义学生类:
class Student{public: Student(int id, string name, int grade) { this->id = id; this->name = name; this->grade = grade; }private: int id; string name; int grade;};
其次通过另一个类实现排序功能(也就是伪函数):
函数对象定义(实现升序排列):
class Function //函数对象,实现排序功能{public: bool operator()(const Student& s1, const Student& s2) const { return s1.grade < s2.grade; }};
本类不写成员函数,构造函数,仅写一个公用方法提供判断。
这个类的思路是:通过类内实现“()”符号的重载,重载的()执行将传入的参数(两个Student类s1,s2),并比较这两个对象实例的成员grade的大小并返回。
通过"重载()"这个操作定义了一个操作函数,只不过这个函数在一个类中,故称函数对象。
后续在main中 调用insert()方法插入student时调用"()"的重载进行比较。
stu.insert(Student(1, "Tom", 90));
main函数的实现:
int main(){ set<Student, Function> stu; //创建set类型的对象stu,并指定排序方式为Function stu.insert(Student(1, "Tom", 90)); stu.insert(Student(2, "Jerry", 40)); stu.insert(Student(3, "Mike", 70)); stu.insert(Student(4, "Lily", 80)); set<Student, Function>::iterator it; ///定义迭代器 //输出set中的元素 for (it = stu.begin(); it!= stu.end(); it++) { cout << it->id << " " << it->name << " " << it->grade << endl; } return 0;}
运行结果:
若要实现降序排列,则修改函数对象的重载:
return s1.grade > s2.grade;
运行结果:
在上面的例子中,函数对象(Function)仅仅定义了比较两个对象成员的bool类型函数,传入set容器中就实现了排序,那么具体是如何实现的呢?
在c++标准库中std::less作为一个函数对象,其主要功能就是重载operator(),使其能够用于比较。此时的"<"和">"并未起到实际作用,仅起到返回true或false,判断排序方法的作用,内容如下:
namespace std { template <class T> struct less { bool operator()(const T& lhs, const T& rhs) const { return lhs < rhs; // 实际上调用了小于运算符 } };}
当然我们也可以通过重载operator<的方式实现自定义的降序排列:
struct MyClass { int value; bool operator<(const MyClass& other) const { return this->value < other.value; // 按照 value 进行比较 }};
两种方法效果一致,不过前者直接使用了set自带的less函数对象,后者通过重载<实现排序。
c++STL还提供了多种比较函数对象,和less用法相似,读者可以自行尝试使用:
greater<T>:用来实现大于比较。equal_to<T>:用于判断相等。not_equal_to<T>:用于判断不相等。greater_equal<T>:用于大于等于比较。less_equal<T>:用于小于等于比较。