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.erasedata 的循环内:哎哟。 正如错误所说,您没有捕获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的主要内容,如果未能解决你的问题,请参考以下文章

c++ unordered_map 自定义key

网站后端_Python+Flask.0008.FLASK响应相关之隐式显式与自定义响应?

深入学习c++--容器

在 boost::unordered_multimap 中循环遍历 equal_range

保证 std::unordered_multimap 中的键唯一性

对 unordered_multimap 键进行平均的更好方法是啥?