📅  最后修改于: 2023-12-03 15:13:56.100000             🧑  作者: Mango
在C++ STL中, std::set
是一个关联容器(associative container),它使用红黑树(Red-Black tree)作为底层数据结构,提供了一系列基于二叉树的搜索/插入/删除操作,以及遍历容器的方式,同时保证了所有元素的顺序性。
std::set
内部默认使用 operator<
运算符进行元素的比较和排序,但是我们还可以通过重载 operator>
运算符,来改变 std::set
容器元素的比较和排序方式。
##语法
一般情况下,重载比较运算符的语法如下:
bool operator>(const T& lhs, const T& rhs);
此处T为任意数据类型。其中,lhs和rhs是两个要比较的对象。
在 std::set
中,重载 operator>
运算符时,语法如下:
bool operator>(const <class_type>& left, const <class_type>& right);
其中,<class_type>
为元素的数据类型。
通过重载 operator>
运算符,我们可以修改 std::set
的默认排序规则(按照升序排序,使用元素自身的 less-than 运算符),实现降序排序或者自定义排序规则。但是需要注意的是,修改排序规则可能会带来性能降低的代价,因此需要评估每种情况下的实际情况。
下面的示例展示了如何定义一个自定义类型 Student
,并通过重载 operator>
运算符,改变 std::set
元素的排序规则(按照分数高低进行排序)。
#include <iostream>
#include <set>
class Student {
public:
Student(const std::string& name, int score): name_(name), score_(score) {}
bool operator>(const Student& rhs) const {
return score_ > rhs.score_;
}
const std::string& GetName() const {
return name_;
}
int GetScore() const {
return score_;
}
private:
std::string name_;
int score_;
};
int main() {
std::set<Student, std::greater<Student>> students({Student("Tom", 90), Student("Bob", 80), Student("Alice", 95)});
for (auto& s : students) {
std::cout << s.GetName() << ": " << s.GetScore() << std::endl;
}
return 0;
}
在本示例中,我们定义了一个名为 Student
的类,包含学生姓名和成绩两个字段,以及一个可以比较不同学生得分大小的运算符重载函数 operator>
。
在 main
函数中,我们使用带有自定义比较函数的 std::set
容器 students
,从而实现以学生分数从高到低的顺序存储学生对象。
输出结果如下:
Alice: 95
Tom: 90
Bob: 80
这个结果和按学生分数从低到高进行排序的结果正好相反。
本文介绍了如何通过重载运算符,改变 std::set
容器元素的默认排序规则,以及如何定义容器自定义比较函数。需要注意的是,修改排序规则可能会带来性能降低的代价,同时在使用自定义比较函数时,需要保证比较函数返回的结果满足传递性(transitivity),即如果 a > b
,b > c
,则必须有 a > c
,否则可能会影响容器的内部一致性。