如何构造元组向量并按Pair式规则排序?附多键排序实例
没问题!针对你这种多键排序的需求,C++ STL里有好几种简单好用的实现方式,我一步步给你讲清楚,包括你提到的tuple用法,还有更直观的方案,保证你能轻松上手~
方法一:用std::tuple直接实现(最快捷)
其实std::tuple的默认排序逻辑正好完全匹配你的需求:先按第一个元素升序,第一个相等就比第二个,第二个再相等就比第三个,完全不用额外写任何比较逻辑。
直接看代码示例:
#include <iostream> #include <vector> #include <tuple> #include <algorithm> int main() { // 将你的三元组转换为tuple的vector std::vector<std::tuple<int, int, int>> elements = { {3, 9, 1}, {1, 5, 2}, {2, 8, 3}, {1, 4, 4}, {1, 6, 5}, {1, 5, 6} }; // 直接调用STL的sort,tuple自带字典序比较规则 std::sort(elements.begin(), elements.end()); // 输出排序结果 for (const auto& t : elements) { std::cout << "(" << std::get<0>(t) << " " << std::get<1>(t) << " " << std::get<2>(t) << ")\n"; } return 0; }
运行这段代码后,输出的结果就是你期望的:(1 4 4)、(1 5 2)、(1 5 6)、(1 6 5)、(2 8 3)、(3 9 1)。
这里的核心是std::tuple的<运算符已经帮我们实现了字典序比较,完全符合你的多键排序规则。
方法二:自定义结构体+重载比较运算符(更直观易扩展)
如果你觉得tuple的std::get<N>写法不够直观,也可以自定义一个结构体,明确写出排序规则,后续要修改逻辑也更方便:
#include <iostream> #include <vector> #include <algorithm> // 定义你的三元组结构体 struct Triple { int key1; int key2; int key3; // 重载小于运算符,明确排序规则 bool operator<(const Triple& other) const { if (key1 != other.key1) { return key1 < other.key1; // 第一键升序 } if (key2 != other.key2) { return key2 < other.key2; // 第一键相等时,第二键升序 } return key3 < other.key3; // 前两键相等时,第三键升序 } }; int main() { std::vector<Triple> elements = { {3, 9, 1}, {1, 5, 2}, {2, 8, 3}, {1, 4, 4}, {1, 6, 5}, {1, 5, 6} }; std::sort(elements.begin(), elements.end()); for (const auto& t : elements) { std::cout << "(" << t.key1 << " " << t.key2 << " " << t.key3 << ")\n"; } return 0; }
这种方法的优势是可读性极强,排序逻辑一目了然,要是以后需要调整某一键的排序方向(比如改成降序),直接修改operator<里的判断即可。
方法三:用Lambda表达式作为比较函数(最灵活)
如果不想定义结构体或者使用tuple,还可以在调用sort时直接传入一个Lambda表达式,临时指定比较规则,适合临时的排序需求:
#include <iostream> #include <vector> #include <array> #include <algorithm> int main() { // 用array存储三元组,也可以用vector<int>等其他容器 std::vector<std::array<int, 3>> elements = { {3, 9, 1}, {1, 5, 2}, {2, 8, 3}, {1, 4, 4}, {1, 6, 5}, {1, 5, 6} }; // 用Lambda自定义比较逻辑,传给sort std::sort(elements.begin(), elements.end(), [](const std::array<int,3>& a, const std::array<int,3>& b) { if (a[0] != b[0]) return a[0] < b[0]; if (a[1] != b[1]) return a[1] < b[1]; return a[2] < b[2]; }); for (const auto& arr : elements) { std::cout << "(" << arr[0] << " " << arr[1] << " " << arr[2] << ")\n"; } return 0; }
这种方法不需要提前定义任何额外类型,直接在排序时指定规则,非常灵活。
以上三种方法都能完美实现你要的排序效果,你可以根据自己的代码场景和习惯选择~
内容的提问来源于stack exchange,提问作者Hafiz Al Masud Ovi
相关产品推荐
相关产品推荐

