# 自定义比较器 使用自定义比较器来排序。 本文部分参考[usaco.guide](https://usaco.guide/gold/custom-cpp-stl)。以下方法均适用于 `set`、`map`、`priority_queue` 容器,以及对 `vector` 进行 `sort` 排序。 ## 方法 1:重载 `<` 运算符(operator overloading) ```cpp #include <bits/stdc++.h> using namespace std; struct Edge { int a, b, w; // 第二个 const 意味着你不能在该成员函数内修改类 Edge 的成员变量 bool operator<(const Edge &y) const { return w < y.w; } }; vector<Edge> edge; /* priority_queue<Edge> pq; set<Edge> s; map<Edge, int> m; */ int main() { int M = 4; for (int i = 0; i < M; ++i) { int a, b, w; cin >> a >> b >> w; edge.push_back({a, b, w}); } sort(edge.begin(), edge.end()); for (Edge e : edge) cout << e.a << " " << e.b << " " << e.w << "\n"; } ``` ### 方法 2:函数 直接使用函数定义比较器。 ```cpp #include <bits/stdc++.h> using namespace std; struct Edge { int a, b, w; }; bool cmp(const Edge &x, const Edge &y) { return x.w < y.w; } vector<Edge> edge; /* priority_queue<Edge, vector<Edge>, decltype(&cmp)> pq(cmp); set<Edge, bool (*)(const Edge &, const Edge &)> v(cmp); set<Edge, decltype(&cmp)> s(cmp); map<Edge, int, decltype(&cmp)> m(cmp); */ int main() { int M = 4; for (int i = 0; i < M; ++i) { int a, b, w; cin >> a >> b >> w; edge.push_back({a, b, w}); } sort(edge.begin(), edge.end(), cmp); for (Edge e : edge) cout << e.a << " " << e.b << " " << e.w << "\n"; } ``` 使用 lambda 表达式定义比较器。 ```cpp vector<Edge> edge; /* priority_queue<Edge, vector<Edge>, decltype(cmp)> pq(cmp); set<Edge, bool (*)(const Edge &, const Edge &)> v(cmp); set<Edge, decltype(cmp)> s(cmp); map<Edge, int, decltype(cmp)> m(cmp); */ auto cmp = [](const Edge &x, const Edge &y) { return x.w < y.w; }; int main() { int M = 4; for (int i = 0; i < M; ++i) { int a, b, w; cin >> a >> b >> w; edge.push_back({a, b, w}); } sort(edge.begin(), edge.end(), cmp); for (Edge e : edge) cout << e.a << " " << e.b << " " << e.w << "\n"; } ``` ## 方法 3:函数对象(functor,function object) functor 是 C++ 中行为类似函数的对象,它是通过在类或结构体里重载运算符 `()` 来实现的。一个例子如下: ```cpp // 定义一个简单的 Functor class Add { public: int operator()(int a, int b) const { return a + b; } }; // 使用 Functor Add add; int result = add(3, 5); // 调用 operator(),返回 8 ``` 使用 functor 来进行排序的例子如下: ```cpp #include <bits/stdc++.h> using namespace std; struct Edge { int a, b, w; }; struct cmp { // 第二个 const 意味着你不能在该成员函数内修改类 cmp 的成员变量 bool operator()(const Edge &x, const Edge &y) const { return x.w < y.w; } }; vector<Edge> edge; /* priority_queue<Edge, vector<Edge>, cmp> pq; set<Edge, cmp> s; map<Edge, int, cmp> m; */ int main() { int M = 4; for (int i = 0; i < M; ++i) { int a, b, w; cin >> a >> b >> w; edge.push_back({a, b, w}); } sort(edge.begin(), edge.end(), cmp()); for (Edge e : edge) cout << e.a << " " << e.b << " " << e.w << "\n"; } ``` 当你需要对元素进行多种比较规则的排序时,优先使用该方法而不是重载 `<` 运算符。 一个有趣的用法是,重载 `<` 运算符会自动生成 functor `less<Edge>`,重载 `>` 运算符会自动生成 functor `greater<Edge>`。 ```cpp #include <bits/stdc++.h> using namespace std; struct Edge { int a, b, w; bool operator>(const Edge &y) const { return w > y.w; } }; vector<Edge> v; int main() { int M = 4; for (int i = 0; i < M; ++i) { int a, b, w; cin >> a >> b >> w; v.push_back({a, b, w}); } sort(v.begin(), v.end(), greater<Edge>()); for (Edge e : v) cout << e.a << " " << e.b << " " << e.w << "\n"; }