Reputation: 491
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!!
Upvotes: 4
Views: 2860
Reputation: 18652
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>
.
Upvotes: 4
Reputation: 11232
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]));
}
}
Upvotes: 2
Reputation: 21058
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.
Upvotes: 1