C++17 自定义二维vector排序:首元素大于第二个元素的对置末尾并按元素和升序
自定义排序比较器的正确实现
首先明确std::sort的比较器必须满足严格弱序要求,简单来说,比较器返回true就代表第一个参数必须严格排在第二个参数前面,不能出现双向矛盾的判断,否则会触发排序的未定义行为。
现有未完成的比较器存在两个核心问题:
- 只判断了当前元素a是否属于要移到末尾的类别,完全没有结合b的类别做跨类的优先级判断
- 当a满足移到末尾的条件时,分支内没有任何返回逻辑,直接跳过后续判断,既会打乱类别优先级,也会破坏严格弱序规则
两层排序逻辑的判断顺序
按照需求,排序的优先级要先按类别分组,再在组内按规则排序,判断顺序不能颠倒:
- 先做跨类优先级判断
- 定义两个布尔标记:
a_should_back代表a是否满足a[0]>a[1](需要移到末尾),b_should_back代表b是否满足同样的条件 - 只要两个元素不属于同一类别:正常类(不需要移到末尾)的元素必须永远排在末尾类的元素前面
- 定义两个布尔标记:
- 同类别下做次级排序
- 两个元素都属于正常类时,才按照两元素的总和做升序排序
- 两个元素都属于末尾类时,没有额外排序要求,保持现有相对顺序即可
完整可运行的比较器代码
std::sort(v.begin(), v.end(), [](const std::vector<int>& a, const std::vector<int>& b) { bool a_should_back = (a[0] > a[1]); bool b_should_back = (b[0] > b[1]); // 跨类优先级判断:不同类别时,正常类元素排在前面 if (a_should_back != b_should_back) { return !a_should_back; } // 同属正常类:按元素总和升序排序 if (!a_should_back) { return (a[0] + a[1]) < (b[0] + b[1]); } // 同属末尾类:无排序要求,直接返回false return false; });
结果校验
针对给出的初始值v=[[10,125],[2,13],[3,2],[1,2]],分类和排序过程如下:
- 先划分类别:
- 正常类(
首元素<次元素):[10,125](和135)、[2,13](和15)、[1,2](和3) - 末尾类(
首元素>次元素):[3,2]
- 正常类(
- 正常类按总和升序排列:
[1,2]→[2,13]→[10,125],最后拼接末尾类元素[3,2] - 最终输出结果完全匹配预期的
v=[[1,2],[2,13],[10,125],[3,2]]
小提示:如果同属末尾类的元素也需要按固定规则排序,只需要在最后那个
return false的分支里替换成对应比较逻辑即可,不会破坏前面的分组优先级。
内容的提问来源于stack exchange,提问作者Rohit gupta
相关产品推荐
相关产品推荐

