You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中使用自定义比较器排序时如何保留同键值元素初始顺序?

问题:按指定字段排序并保留同值元素原始顺序

用户提供的C++代码:

std::vector<std::vector<std::string>> vect{
{"abc","def","2"},
{"def","ghi","2"},
{"abc","def","2"},
{"abc","def","3"}};
std::sort(vect.begin(),vect.end(),
[](const std::vector<std::string>& a,const std::vector<std::string>& b){
/*if(a[2]!=b[2]) return a[2]>b[2];*/});

期望实现:

  • 元素第2个索引值不同时,按该值降序排列
  • 元素第2个索引值相同时,保留其在原容器中的初始顺序

预期结果:

vect={
{"abc","def","3"},
{"abc","def","2"},
{"def","ghi","2"},
{"abc","def","2"}};

但使用std::sort时,同值元素的原始顺序无法保留,原因是**std::sort是不稳定排序**——即使比较函数对两个元素返回false(即判定为“相等”),std::sort仍可能交换它们的位置,不会保证原始顺序。


解决方案

方法一:使用std::stable_sort

std::stable_sort是稳定排序算法,会严格保留相等元素的原始相对顺序。只需替换std::sort为std::stable_sort,并完善比较函数:

#include <algorithm>
#include <vector>
#include <string>

int main() {
    std::vector<std::vector<std::string>> vect{
        {"abc","def","2"},
        {"def","ghi","2"},
        {"abc","def","2"},
        {"abc","def","3"}};
    
    std::stable_sort(vect.begin(), vect.end(),
        [](const std::vector<std::string>& a, const std::vector<std::string>& b){
            return a[2] > b[2]; // 仅按第2个元素降序,同值时保留原顺序
        });
    
    // 此时vect已符合预期结果
    return 0;
}

方法二:绑定原始索引后使用std::sort

如果必须使用std::sort,可以给每个元素绑定它在原容器中的索引,排序时先按目标字段降序,再按索引升序,从而间接保留原始顺序:

#include <algorithm>
#include <vector>
#include <string>
#include <utility>

int main() {
    std::vector<std::vector<std::string>> vect{
        {"abc","def","2"},
        {"def","ghi","2"},
        {"abc","def","2"},
        {"abc","def","3"}};
    
    // 为每个元素绑定原始索引
    std::vector<std::pair<std::vector<std::string>, int>> indexed_vect;
    for (int i = 0; i < vect.size(); ++i) {
        indexed_vect.emplace_back(vect[i], i);
    }
    
    // 排序:先按第2个元素降序,同值时按索引升序(即原始顺序)
    std::sort(indexed_vect.begin(), indexed_vect.end(),
        [](const auto& a, const auto& b){
            if (a.first[2] != b.first[2]) {
                return a.first[2] > b.first[2];
            }
            return a.second < b.second;
        });
    
    // 将排序后的元素提取回原容器
    vect.clear();
    for (const auto& item : indexed_vect) {
        vect.push_back(item.first);
    }
    
    // 此时vect已符合预期结果
    return 0;
}

内容的提问来源于stack exchange,提问作者user814412

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 13:41:51