将多个地图中的相同关键项汇总在一起?

时间:2015-03-25 23:41:56

标签: c++ c++11

我之前已经在这里问过这个问题:

stl::multimap - how do i get groups of data?

但答案是:

pair<Iter, Iter> range = my_multimap.equal_range("Group1");
int total = accumulate(range.first, range.second, 0);
当我这样做时,

不会为我编译:

pair<multimap<int32_t, float>::iterator, multimap<int32_t, float>::iterator> range = multimap.equal_range(an_int);
float total = accumulate(range.first, range.second, 0);

这是在GCC 4.8

有没有人可以确认他们是否可以编译这个/提供正确答案?

2 个答案:

答案 0 :(得分:5)

此代码存在四个问题:

  1. 你有太多关闭尖括号。
  2. 你的多图可能不应该被命名为multimap。 (虽然这个可能不会导致编译错误,但很明显你不应该这样做。)
  3. 取消引用多图迭代器会提供键值,而不仅仅是值。当然,您无法直接将这些与std::accumulate相加。
  4. 即使您使用多重集而不是多重映射执行此操作,因此#3不适用,传递0作为初始值将导致所有浮点数被截断,因为它会推断类型{ {1}}对于累加器...所以你可能会得到错误的答案。
  5. 看起来你在2003年陷入困境,因为你实际写出了int的返回类型,所以我猜你没有lambdas或range-for-loops。

    equal_range

    或者完全避免pair<multimap<int32_t, float>::iterator, multimap<int32_t, float>::iterator> range = M.equal_range(an_int); float total = 0; for (multimap<int32_t, float>::iterator I = range.first; I != range.second; ++I) { total += I->second; } 和那个讨厌的宣言......

    equal_range

    编辑:好的,所以你确实拥有C ++ 11支持。所以你可以这样做:

    float total = 0;
    for (multimap<int32_t, float>::iterator I = M.lower_bound(an_int);
         I != M.end() && I->first == an_int;
         ++I) {
        total += I->second;
    }
    

    (注意:如果你有C ++ 14支持,你甚至可以在lambda中用auto range = M.equal_range(an_int); float total = accumulate(range.first, range.second, 0.0, [](float x, pair<int32_t, float> y) { return x + y.second; }); 替换pair<int32_t, float>。)

答案 1 :(得分:3)

我相信gcc 4.8已经支持C ++ 11重新定义auto 1 和lambdas,所以你应该可以使用:

auto range = multimap.equal_range(an_int);
std::cout << std::accumulate(range.first, range.second, 0, 
    [](int a, std::pair<int32, float> b) { return a + b.second; });

[当然,您需要指定您的 multimap对象的名称,其中包含multimap。]

顺便说一句,由于您希望结果为float,因此您可能希望将初始值更改为float,因此累积在float s上完成,而不是int s:

std::cout << std::accumulate(range.first, range.second, 
    0.0f,
    [](float a, std::pair<int32, float> b) { return a + b.second; });

1.带有-std=C++0x标志。 功能