【发布时间】:2016-11-19 22:38:45
【问题描述】:
我需要一个无符号整数列表中每个出现值的出现计数。 IE。如果通过序列 [ 3, 6, 9, 3, 9 ] 我想要 [ { 3, 2}, {6, 1}, {9, 2} ]。
这些值是随机的 32 位无符号整数(范围为 1 到 1,000,000,000)。结果可以存储在任何数据结构中(只要它们可以线性迭代),虽然值排序是理想的,但这是速度之后的次要问题。
目前我有 -
T UniqueCount(std::vector<unsigned> &A)
{
std::unordered_map<unsigned,unsigned> value_counts;
for(unsigned val : A) {
value_counts[val]++;
}
A.clear();
...
}
分析显示 std::unordered_map 比 std::map 快。
有没有更好的方法呢? /更快的方式?还有一点值得注意,因为用例(count > 4)可以记为4。
这是目前的一个瓶颈,因此虽然首选标准容器,但如果性能提升值得额外的维护成本,则可以考虑定制一些容器。
【问题讨论】:
-
PS 你可以直接将计数存储到
_vals,比如用_vals[*it] ++(或value_counts[*it] ++或其他什么,很难说)替换循环中的所有内容,因为operator []@987654321 @(在您的情况下为 0)并返回对该值的引用。 -
谢谢 - @krzaq 提出了同样的建议。更新了我的代码。
-
您可能想解释为什么这段代码是一个瓶颈。是否经常重新生成一组新的随机值?如果是这样,为什么不在生成随机值的过程中生成计数,而不是之后呢?另外(次要)请记住,
unsigned不能保证能够表示 32 位值,因此在移植代码时可能存在正确性问题。 -
A作为非常量引用传递——是否允许修改?具体来说,是否允许排序? -
@ildjarn 是的 - 可以修改它。但是排序将是 nlogn,而当前代码是 O(N)。说我还没有对它进行分类。
标签: c++ performance c++11