0008容器之unordered_multimap
Posted 寂静_星空
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了0008容器之unordered_multimap相关的知识,希望对你有一定的参考价值。
#include <list>
#include<iostream>
#include<vector>
#include<stdexcept>
#include<string>
#include<cstdlib>//abort()
#include<cstdio>//snprintf();整数转字符
#include<ctime>
#include<algorithm>
#include<array>
#include<string>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
using namespace std;
#define NUM 1000000
int main()
unordered_multimap<long, string> c;
char buf[10];
clock_t timeStart = clock();
long target = 99999;
for (long i = 0; i < NUM; ++i)
snprintf(buf, 10, "%d", rand());
c.insert(pair<long,string>(i,buf));
cout << "毫秒: " << (double((clock() - timeStart))/CLOCKS_PER_SEC * 1000 ) << endl;
cout << "undered_multiset.size() = " << c.size() << endl;
cout << "undered_multiset.max_size()= " << c.max_size() << endl;
cout << "undered_multiset.bucket_count()= " << c.bucket_count() << endl;
cout << "undered_multiset.load_factor()= " << c.load_factor() << endl;
cout << "undered_multiset.max_load_factor()= " << c.max_load_factor() << endl;
cout << "undered_multiset.max_bucket_count()= " << c.max_bucket_count() << endl;
for (unsigned i = 0; i < 20; ++i)
cout << "bucket #" << i << " has " << c.bucket_size(i) << " elements." << endl;
timeStart = clock();
auto pItem = c.find(target);
cout << "c.find() 毫秒: " << (double((clock() - timeStart))/CLOCKS_PER_SEC * 1000 ) << endl;
if (pItem != c.end())
cout << "find value: " << pItem->second << endl;
else
cout << "not find " << endl;
return 0;
对 unordered_multimap 键进行平均的更好方法是啥?
【中文标题】对 unordered_multimap 键进行平均的更好方法是啥?【英文标题】:Is the a better way to do an average of a unordered_multimap key?对 unordered_multimap 键进行平均的更好方法是什么? 【发布时间】:2019-12-03 16:58:17 【问题描述】:我正在我的 unordered_multimap 中搜索获取一个键的所有值,这实际上是堆叠一个 int 和一个表示执行时间(以纳秒为单位)的值。我需要用 一个平均键来替换多键的所有值。
我尝试了一些代码,这个实际上是最有价值的:
std::unordered_multimap<int, std::chrono::nanoseconds> data;
std::chrono::nanoseconds average;
// *filling my map with value*
for (auto & pair : data)
auto range = data.equal_range(pair.first);
for_each (
range.first,
range.second,
[](std::unordered_multimap<int, std::chrono::nanoseconds>::value_type& x)
average = average + x.second;
);
average = average / data.count(pair.first);
data.erase(pair.first);
data.insert(pair.first, average);
我得到的错误error: 'average' is not captured : average = average + x.second;
【问题讨论】:
我不明白这个问题。为什么不在更高的范围内声明average
?
The problem is that average isn't defined out of the for_each loop
- 所以在 for_each 循环中定义平均值。问题解决了!
data.erase
在data
的循环内:哎哟。
正如错误所说,您没有捕获average
。将其添加到 lambda 的捕获列表中。
我做了更改并在更大范围内进行了声明,但仍然无法正常工作
【参考方案1】:
而不是std::for_each
,使用std::accumulate
。
请注意,在 ranged-for 中从 std::unordered_multimap
中删除条目是未定义的行为。填充不同的容器更安全。
std::unordered_multimap<int, std::chrono::nanoseconds> data;
// *filling my map with value*
std::unordered_multimap<int, std::chrono::nanoseconds> new_data;
for (auto it = data.begin(); it != data.end(); ++it)
auto range = data.equal_range(it->first);
auto average = std::accumulate (
range.first,
range.second,
std::chrono::nanoseconds0,
[](auto sum, auto & x)
return sum + x.second;
) / std::distance(range.first, range.second);
new_data.emplace(key, average);
data.swap(new_data);
或者,如果你有 C++17,std::transform_reduce
。
std::transform_reduce(
range.first,
range.second,
std::chrono::nanoseconds0,
std::plus<>,
[](auto & x) return x.second;
)
【讨论】:
我试过这个,但是有很多错误,根本无法编译emplace
真的总是安全的吗?我想它不会导致重新散列,因为大小不会增加,但是新元素的迭代器是否保证在从erase
返回的it
之前排序?
效果很好,在你编辑后我确实改变了,一切都好!谢谢
@walnut 也许?之后填写decltype(data) new_data;
和data.swap(new_data);
可能更安全
@Caleth 是的,那是我的建议。还允许删除 erase
并使用普通的迭代器循环。仅根据 cppreference,因为 C++14 保证 erase
保留迭代器的顺序,并且在这方面它没有说明 emplace
。以上是关于0008容器之unordered_multimap的主要内容,如果未能解决你的问题,请参考以下文章
网站后端_Python+Flask.0008.FLASK响应相关之隐式显式与自定义响应?
在 boost::unordered_multimap 中循环遍历 equal_range