最稳妥方案是用 std::unordered_map 统计频次,平均 o(1) 效率高;若需排序则选 std::map;浮点数作键需谨慎,避免精度问题;小范围非负整数可用 vector 桶计数优化。

用 std::map 或 std::unordered_map 统计最稳妥
原生 C++ 数组不自带计数功能,硬写循环遍历统计容易漏边界、错逻辑。直接用标准容器更安全,也符合现代 C++ 习惯。
推荐优先选 std::unordered_map:平均 O(1) 插入和查找,适合大数组;若需按元素值排序输出,再换 std::map(O(log n))。
-
std::unordered_map<t int></t>的键是数组元素类型T(如int、char),值是出现次数 - 遍历时用
auto&避免拷贝,尤其元素是字符串或自定义类型时 - 注意:若数组含
float或double,别直接用作unordered_map键——浮点精度会导致误判,改用std::map+ 自定义比较,或转为整数倍数后处理
int arr[] = {1, 2, 2, 3, 2, 4};
int n = sizeof(arr) / sizeof(arr[0]);
std::unordered_map<int int> count;
for (int i = 0; i <h3>对小范围整数用 <code>std::vector</code> 桶计数更快</h3>
<p>当数组元素全是非负整数,且最大值已知且不太大(比如 </p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill2659" title="C++"><img
src="https://img.php.cn/upload/skill/000/000/081/178927213426672.jpg" alt="C++" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill2659" title="C++" class="overflowclass">C++</a>
<p class="overflowclass">"空空如也"</p>
</div>
<a rel="nofollow" href="/xiazai/skill2659" title="C++" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<ul>
<li>先用 <code>std::vector<int>(max_val + 1)</int></code> 初始化全 0 的桶</li>
<li>遍历数组,对每个 <code>arr[i]</code> 执行 <code>buckets[arr[i]]++</code>
</li>
<li>如果元素可能为负,统一加偏移量:例如范围是 [-1000, 1000],就开大小 2001 的 vector,访问时用 <code>arr[i] + 1000</code>
</li>
<li>别忘了检查 <code>arr[i]</code> 是否越界,否则触发未定义行为</li>
</ul>
<pre class="brush:php;toolbar:false;">
// 假设 arr 元素 ∈ [0, 99]
std::vector<int> buckets(100, 0);
for (int x : arr) {
if (x >= 0 && x <h3>用 <code>std::count</code> 只适合单次查一个值</h3>
<p>如果你只是想快速知道某个特定值出现了几次,不用建完整映射,<code>std::count</code> 最简洁,底层就是朴素遍历,但语义清晰、无额外内存分配。</p>
<ul>
<li>头文件是 <code><algorithm></algorithm></code>
</li>
<li>只适用于已知要查哪个值的场景,比如“统计数组里有多少个 7”</li>
<li>对整个数组做多次 <code>std::count</code>(比如查 1、2、3…)效率远低于一次哈希扫描,时间复杂度 O(n × 查询次数)</li>
<li>不能用于自定义类型,除非重载了 <code>operator==</code>
</li>
</ul>
<pre class="brush:php;toolbar:false;">
#include <algorithm>
int cnt = std::count(std::begin(arr), std::end(arr), 2); // 返回 3
</algorithm>
原始数组 + 手写循环要注意的坑
有些场景受限于环境(比如嵌入式、禁用 STL),必须手写。这时候最容易出问题的是初始化、边界和类型匹配。
- 手动清零计数数组:别只写
int count[100] = {},要确保长度覆盖全部可能取值,且用= {0}或std::fill显式初始化 - 用
sizeof(arr)/sizeof(*arr)算长度,别硬写数字,否则增删元素时易不同步 - 如果数组是
const或指针传入(如int* arr),sizeof失效,必须额外传长度参数 - 字符数组记得区分
'a'和"a":前者是char,后者是const char*,不能直接当 map 键用
C++ 数组计数本身不难,难的是根据数据特征(范围、类型、查询模式、环境约束)选对方法。用错容器或忽略边界检查,比写错逻辑更容易引发运行时崩溃或静默错误。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










