如何找到2张地图中常见的所有键?

时间:2012-10-11 16:40:21

标签: c++ stl map vector

我有3张地图:

map<string, vector<int> > map1
map<string, vector<int> > map2
map<string, vector<int> > map3

我需要创建第三个地图,其中map1和map2中存在的所有字符串及其相应的向量。事实是,即使字符串相同,它们的向量也可能不同,我必须将来自两个公共字符串的所有向量附加到1个向量中。 这就是我正在尝试但我有点失落:

for(map<string, vector<int> >::iterator it1=map1.begin(); it1 != map1.end(); it1++)
{
    string name = (*it1).first;
    for(map<string, vector<int> >::iterator it2=map2.begin(); it2 != map2.end(); it2++)
    {
        string name2 = (*it2).first;
        if (name == name2)
        {
            map3[name2] = (*it2).second;

        }
    }
}

非常感谢你的帮助!!

3 个答案:

答案 0 :(得分:3)

由于地图是有序的,您可以在线性时间内完成此操作。这是完成任务的一种可能方式:

#include <map>
#include <string>
#include <vector>

typedef std::vector<int> vec_t;
typedef std::map<std::string, vec_t> map_t;
typedef map_t::const_iterator iter_t;

int main()
{
    map_t map1, map2, map3;

    iter_t it1 = map1.begin();
    iter_t it2 = map2.begin();

    while (it1 != map1.end() && it2 != map2.end()) {
        if (it1->first < it2->first) {
            ++it1;
        } else if (it2->first < it1->first) {
            ++it2;
        } else { // equal keys
            vec_t temp(it1->second);
            temp.insert(temp.end(), it2->second.begin(), it2->second.end());
            map3[it1->first].swap(temp); // swap contents to new map entry
            ++it1;
            ++it2;
        }
    }
}

请注意,这假设地图键排序是默认的less<Key>

答案 1 :(得分:2)

你可以做到

#include <algorithm>  // for std::copy
#include <iterator>   // for std::back_inserter
#include <map>
...

for(auto it = map1.begin(); it != map1.end(); ++it)
{
   auto fit = map2.find(it->first);
   if(fit != map2.end()
   {
      map3[it->first] = it->second;
      std::copy(fit->second.begin(), fit->second.end(), std::back_inserter(map3[it->first]));
   }
}

答案 2 :(得分:1)

一个解决方案是

map3 = map1;
typedef map<string, vector<int> > map_type;

for(map_type::iterator itr = map2.begin(); itr != map2.end(); ++itr)
{
    vector<int>& ref = map3[itr->first];
    ref.insert(ref.end(), itr->second.begin(), itr->second.end());
}

首先将第一张地图中的所有条目复制到目的地。然后,对于地图中的每个条目,它会在输出映射中查找相应的条目。如果它尚不存在,则会创建一个新的向量(通过map::operator[]),否则,它将返回对现有的引用。然后将第二个映射中的向量附加到结果中已经存在的向量中。

缺点是你在目标地图中一遍又一遍地搜索结果地图,这似乎有点过分。由于两个映射都已排序,因此它应该能够在线性时间内完成,而不是N-log-N时间。