2017-10-19 97 views
0

我已创建的形式的两个映射:合并两个地图C++

[事件号] [质量]称为地图results_JMass

[事件号] [动量]称为地图results_PhotonPt

两个图都有相同的键(事件号),它是一个整数并且包含双精度值。我想创建形式的第三张地图:

[事件数] [质量] [势头]

我知道我需要使用

std::map <Int_t, std::vector< pair <Double_t,Double_t> > > new_map; 

但我不知道如何将两张地图结合起来创造出第三张。

这是我想出了:

for (auto& kv3 : results_JMass) { //Iterates the data with kv3 as the iterator and the results_jMass what kv3 is iterating through 
    event_number = kv3.first; //Iterator for the first index, i.e the events 
    m = kv3.second; //iterator for the second index i.e the masses 

    new_map [event_number].first = m; 

    for (auto&kv4: results_PhotonPt) { 
event_number = kv4.first; 
p = kv4.second; 

new_map [event_number].second = p; 
    } 
} 
+1

,保证包含相同的事件号的两个地图? – Steve

+0

与您的问题无关,但“Int_t”和“Double_t”是什么?他们是普通的'int'还是'double'?为什么使用自定义类型名称? –

+4

在我看来,表达地图的正确方法应该是:'std :: map > new_map;' – Amadeus

回答

1

如果你是100%肯定,这两个地图都有一模一样的钥匙,然后一个循环就足够了:

std::map < Int_t, pair <Double_t,Double_t> > new_map; 
auto it = second_map.begin(); 
for(const auto &p : first_map) 
    new_map.emplace(p.first, std::make_pair(p.second, (it++)->second)); 

或C++ 98

std::map < Int_t, pair <Double_t,Double_t> > new_map; 
second_map_type::const_iterator it2 = second_map.begin(); 
for(first_map_type::const_iterator it1 = first_map.begin(); it1 != first_map.end(); ++it1) 
    new_map.insert(std::make_pair(it1->first, std::make_pair(it1->second, (it2++)->second))); 
+0

假定使用C++ 11,但没有说明问题。 – Steve

+1

@Steve这是6年的标准,我想我们可以承担它,除非另有说明。无论如何,使用C++ 98 – Slava

+0

重写它非常简单,那么为什么在它上面有一个单独的标签,如果C++意味着暗示C++ 11? – Steve

2

假设你的意思是:

std::map < Int_t, pair <Double_t,Double_t> > new_map; 

遍历第一张地图,并使用键和值添加到您的新地图:

new_map [event_number].first = mass; 

然后迭代第二张地图,然后将密钥和值添加到新地图:

new_map [event_number].second = momentum; 

我已经承担了2个源地图包含事件编号完全相同的名单,只是用不同的数据 - 如果没有,你会得到new_map某些条目只包含数据

的一个或其他
+0

谢谢,是的,这两个源地图包含完全相同的事件号码列表,但数据不同。 因此,我在for循环中迭代第一个映射,然后在第一个for循环内循环遍历第二个映射,还是完全单独循环? –

+0

@AmyTee'new_map [event_number] = {mass_map [event_num],momentum_map [event_num]}'应该足够了。不需要多个语句或临时变量。使用['std :: transform'](http://en.cppreference.com/w/cpp/algorithm/transform)和[lambda](http://en.cppreference。com/w/cpp/language/lambda)可以将其缩短得更多。 –

+1

如果您已经在迭代其中一个地图来获取event_number,那么可以使用'new_map [event_number] = {mass,momentum_map [event_number]}',并保存一个额外的查找。 Lambdas需要C++ 11,这在原始问题中没有提到。 – Steve

0

我们可以使用类似的算法来set_intersect,而在同一时间证明了输入数据是(几乎)零成本正确:

#include <map> 
#include <utility> 
#include <limits> 

using mass_map = std::map<int, double>; 
using moment_map = std::map<int, double>; 

using mass_moment_map = std::map < int, std::pair <double,double> >; 

bool merge_mass_and_moment(mass_map const& mass, 
          moment_map const& moment, 
          mass_moment_map& target, 
          mass_moment_map& exceptions) 
{ 
    target.clear(); 
    exceptions.clear(); 

    auto current_mass = mass.begin(); 
    auto current_moment = moment.begin(); 

    while (current_mass != mass.end() && current_moment != moment.end()) 
    { 
     if (current_mass->first < current_moment->first) 
     { 
      exceptions.emplace(current_mass->first, 
           std::make_pair(current_mass->second, std::numeric_limits<double>::infinity())); 
      ++ current_mass; 
     } 
     else if (current_moment->first < current_mass->first) 
     { 
      exceptions.emplace(current_moment->first, 
           std::make_pair(std::numeric_limits<double>::infinity(), current_moment->second)); 
      ++ current_moment; 
     } 
     else 
     { 
      target.emplace(current_moment->first, 
          std::make_pair(current_mass->second, current_moment->second)); 
      ++current_mass; 
      ++current_moment; 
     } 
    } 

    while (current_mass != mass.end()) 
    { 
     exceptions.emplace(current_mass->first, 
          std::make_pair(current_mass->second, std::numeric_limits<double>::infinity())); 
     ++ current_mass; 
    } 

    while(current_moment != moment.end()) 
    { 
     exceptions.emplace(current_moment->first, 
          std::make_pair(std::numeric_limits<double>::infinity(), current_moment->second)); 
     ++ current_moment; 
    } 

    return exceptions.empty(); 
}