用 std::unordered_map 统计频次再两次遍历求众数是最简健壮方案:先建值→频次映射,再找最大频次,最后收集所有对应值;范围有限时可用 vector 优化;排序法不适用只读或大数组场景。

用 std::map 统计频次是最直接可靠的方法
数组没有内置众数计算功能,必须手动统计每个元素出现次数。用 std::map<int int></int>(或 std::unordered_map)记录值→频次的映射,是标准且不易出错的选择。它自动处理重复键、支持任意整型/可比较类型,且逻辑清晰。
常见错误是试图用 std::count 对每个元素单独遍历——时间复杂度 O(n²),对稍大数组(比如 n > 1e4)就明显卡顿。而一次遍历 + map 插入是 O(n log n)(map)或平均 O(n)(unordered_map),更实用。
示例关键片段:
std::unordered_map<int int> freq;
for (int x : arr) freq[x]++;
int mode = arr[0], max_count = 0;
for (const auto& p : freq) {
if (p.second > max_count) {
max_count = p.second;
mode = p.first;
}
}</int>
遇到多个众数时,std::vector 存所有候选值
众数不唯一是常见场景(如 {1,1,2,2,3} 有两个众数)。如果只记第一个最大频次的值,会漏结果。必须先扫一遍确定最高频次 max_count,再扫一遍收集所有满足 freq[x] == max_count 的 x。
容易踩的坑:
- 在单次遍历中边更新
max_count边清空/重置结果 vector —— 可能丢掉之前已发现的众数 - 用
==比较浮点数组元素频次(不该用浮点作 map 键,精度问题会导致统计失效)
正确做法分两步:先求 max_count,再 gather:
int max_count = 0;
for (const auto& p : freq) max_count = std::max(max_count, p.second);
std::vector<int> modes;
for (const auto& p : freq) {
if (p.second == max_count) modes.push_back(p.first);
}</int>
数组元素范围有限时,用 vector 代替 map 更快更省
如果已知所有元素都在小范围内(比如 0–1000 或 -5000 到 5000),直接用 std::vector 当哈希表,下标即值,避免 map 的树/哈希开销。既快又无内存碎片风险。
注意点:
- 要处理负数:偏移量平移,如范围 [-1000,1000] → 开
vector<int>(2001)</int>,访问时用x + 1000 - 别越界:务必确认输入全在预设范围内,否则运行时崩溃或静默错误
- 空间换时间:若范围过大(如 int 全集),vector 占几百 MB,绝对不能用
例如非负小整数:
std::vector<int> freq(1001, 0); // 假设元素 ∈ [0,1000] for (int x : arr) freq[x]++; // 后续同上找 max_count 和 modes</int>
原始数组不可修改?别用 std::sort + 遍历替代 map
有人想先排序再线性扫描求众数,看似省空间。但前提是允许修改原数组或能复制一份。如果数组是 const、只读引用、或内存敏感(如嵌入式场景不允许拷贝),这条路就走不通。
而且排序本身是 O(n log n),常数因子比 hash map 大;若用 std::partial_sort 优化也没意义——众数无法局部排序推断。
真正要注意的是:C++ 没有“求数组众数”的标准算法函数,std::mode 不存在,std::nth_element 也帮不上忙。所有方案都得自己组合基础容器和逻辑。
最简健壮路径就是 unordered_map + 两次遍历——写法直白,边界清楚,调试方便。复杂点在于你得自己判断是否多众数、是否需排序输出、以及元素类型能否做 hash 或比较。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











