How do I find all the keys common in 2 maps?

雨燕双飞 提交于 2020-01-04 03:50:56

问题


I have 3 maps:

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

I need to create a third map with all the strings existing in both map1 and map2 with their corresponding vectors. Thing is, even if the strings are same, their vectors can be different and i have to append all the vectors from both the common strings into 1 vector. This is what I'm trying but I'm kind of lost:

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;

        }
    }
}

Thanks so much for your help!!


回答1:


Since the maps are ordered you can do this in linear time. This is one possible way to do the task:

#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;
        }
    }
}

Note that this assumes the map key ordering is the default less<Key>.




回答2:


You can do

#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]));
   }
}



回答3:


One solution is

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());
}

This first copies all entries from the first map into the destination. It then, for each entry in the map, looks up the corresponding entry in the output map. If it didn't already exist, it creates a new vector (via map::operator[]), otherwise, it returns the reference to the existing on. The vector in the second map is then appended to the vector already in the result.

The downside is you're searching the resulting map over and over again in the destination map, which seems to be a bit excessive. Since both maps are sorted, it should be able to do it in linear time, instead of N-log-N time.



来源:https://stackoverflow.com/questions/12844453/how-do-i-find-all-the-keys-common-in-2-maps

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!