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

如何对C++ std::unordered_map进行稳定排序——保留相等元素插入顺序

解决思路

我之前也碰到过类似的需求,std::unordered_map本身是哈希表实现的,完全不保留插入顺序,而且默认没有排序能力。要实现按值(单词出现次数)排序,同时保证值相等时插入更早的元素排在前面,核心是要手动记录每个单词的插入顺序,然后在排序时把「出现次数」作为第一关键字,「插入顺序」作为第二关键字。

步骤1:扩展存储结构

我们需要把unordered_map的value从单纯的int(出现次数),改成包含「出现次数」和「插入序号」的结构。比如定义一个可读性更好的结构体:

struct WordStats {
    int occurrence;     // 单词出现次数
    size_t insert_seq;  // 插入顺序标记,数值越小表示插入时间越早
};

对应的哈希表类型就变成std::unordered_map<std::string, WordStats>。

步骤2:插入元素时记录插入顺序

需要维护一个计数器,每次插入新单词时分配当前计数器值,然后计数器自增;如果是已存在的单词,只更新出现次数,不改动插入顺序:

std::unordered_map<std::string, WordStats> word_counter;
size_t order_tracker = 0;

// 插入或更新单词的工具函数
void update_word(const std::string& word) {
    auto iter = word_counter.find(word);
    if (iter != word_counter.end()) {
        // 单词已存在,仅增加出现次数
        iter->second.occurrence++;
    } else {
        // 新单词,记录插入顺序
        word_counter[word] = {1, order_tracker++};
    }
}

步骤3:转存为vector并执行排序

unordered_map无法直接排序,我们需要把它的键值对转存到std::vector中,再用自定义比较器排序:

// 将哈希表元素转存到vector
std::vector<std::pair<std::string, WordStats>> sorted_list(word_counter.begin(), word_counter.end());

// 自定义排序规则:先按出现次数排序(这里用降序,按需调整),次数相同时按插入顺序升序
std::sort(sorted_list.begin(), sorted_list.end(),
    [](const auto& lhs, const auto& rhs) {
        if (lhs.second.occurrence != rhs.second.occurrence) {
            return lhs.second.occurrence > rhs.second.occurrence;
        } else {
            // 次数相等时,插入顺序更早的元素排在前面
            return lhs.second.insert_seq < rhs.second.insert_seq;
        }
    });

效果验证

比如依次插入:"apple"、"banana"、"apple"、"cherry"、"banana",最终排序结果会是:

  • "apple"(次数2,插入序0)排在最前
  • 然后是"banana"(次数2,插入序1)
  • 最后是"cherry"(次数1,插入序2)
    完全符合「值相等时插入早的元素优先」的稳定性要求。

简化方案(可选)

如果不想定义结构体,也可以用std::pair<int, size_t>作为value,第一个元素存出现次数,第二个存插入顺序,逻辑完全一致,只是可读性稍弱。另外这里不需要用std::stable_sort——因为我们的比较器已经把插入顺序作为第二关键字,普通的std::sort就能保证值相等时的顺序。

内容的提问来源于stack exchange,提问作者A. Sarid

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:48:52