如果我有两个stl向量vect1,vect2和我想从它们生成一个映射,那么vect1中的第一个元素将对应于vect2中的第一个元素,依此类推。 我怎样才能以最简单的方式做到这一点?
答案 0 :(得分:8)
std::vector<int> a, b;
// fill vectors here...
std::map<int, int> m;
assert(a.size() == b.size());
for (size_t i = 0; i < a.size(); ++i)
m[a[i]] = b[i];
答案 1 :(得分:6)
这是一个使用标准库函数(和C ++ 0x lambdas)的解决方案。
const int data1[] = { 0, 2, 4, 6, 8 };
const int data2[] = { 1, 3, 5, 7, 9 };
std::vector<int> vec1(data1, data1 + 5);
std::vector<int> vec2(data2, data2 + 5);
std::map<int,int> map;
// create map
std::transform(vec1.begin(), vec1.end(), vec2.begin(), std::inserter(map, map.end()), [](int a, int b)
{
return std::make_pair(a, b);
});
// display map
std::for_each(map.begin(), map.end(), [](const std::pair<int,int>& p)
{
std::cout << p.first << "," << p.second << "\n";
});
注意:这假定vec1.size()不大于vec2.size()。
答案 2 :(得分:3)
我们将使用需要2个输入序列的std::transform版本。 (众所周知,它看起来像是一个单一序列的那个)。
您可以传递std::make_pair<v1::value_type, v2::value_type>
作为变换器(op),因此在您的情况下
std::vector<int> vec1, vec2;
std::map< int, int > mergedMap;
std::transform( vec1.begin(), vec1.end(), vec2.begin(),
std::inserter(mergedMap, mergedMap.end() ), std::make_pair<int const&,int const&> );
我已经测试了代码,它可以很好地编译GNU 4.3.2
(我现在也用C ++ 11进行了测试。当我改变make_pair以获取int const&amp;而不是int时,它可以工作。
如果两个输入序列的长度不同,如果第一个较短,则会很好,第二个序列中的后面的元素将被忽略。如果第一个更长,则会产生未定义的行为。
答案 3 :(得分:1)
以下是使用boost zip_iterator
#include <iostream>
#include <algorithm>
#include <string>
#include <map>
#include <vector>
#include <boost/iterator/zip_iterator.hpp>
#include <boost/tuple/tuple.hpp>
// this is our map type
typedef std::map<int, std::string> map_t;
// this functor will be called for each "pair"
struct map_adder :
public std::unary_function<const boost::tuple<const int&, const std::string&>&, void>
{
map_adder(map_t& my_map) : _my_map(my_map){}
void operator()(const boost::tuple<const int&, const std::string&>& t) const
{
_my_map.insert(std::make_pair(t.get<0>(), t.get<1>()));
}
private:
mutable map_t& _my_map;
};
int main(void)
{
// test setup
std::vector<int> keys;
std::vector<std::string> values;
keys.push_back(1);
keys.push_back(2);
keys.push_back(3);
keys.push_back(4);
values.push_back("1");
values.push_back("2");
values.push_back("3");
values.push_back("4");
std::vector<int>::const_iterator beg1 = keys.begin();
std::vector<int>::const_iterator end1 = keys.end();
std::vector<std::string>::const_iterator beg2 = values.begin();
std::vector<std::string>::const_iterator end2 = values.end();
// destination
map_t my_map;
// functor to actually add
map_adder adder(my_map);
// simply iterate over...
std::for_each(
boost::make_zip_iterator(
boost::make_tuple(beg1, beg2)
),
boost::make_zip_iterator(
boost::make_tuple(end1, end2)
),
adder
);
std::cout << "size of map: " << my_map.size() << std::endl;
return 0;
}
好的,这是使用std::transform
的更简单的版本,我不知道已经存在的可以将boost::tuple
转换为std::pair
的内容因此我的功能很简单......
#include <iostream>
#include <algorithm>
#include <string>
#include <iterator>
#include <map>
#include <vector>
#include <boost/iterator/zip_iterator.hpp>
#include <boost/tuple/tuple.hpp>
// this is our map type
typedef std::map<int, std::string> map_t;
map_t::value_type adapt_tuple(const boost::tuple<const map_t::key_type&, const map_t::mapped_type&>& t)
{
return map_t::value_type(t.get<0>(), t.get<1>());
}
int main(void)
{
std::vector<int> keys;
std::vector<std::string> values;
keys.push_back(1);
keys.push_back(2);
keys.push_back(3);
keys.push_back(4);
values.push_back("1");
values.push_back("2");
values.push_back("3");
values.push_back("4");
std::vector<int>::const_iterator beg1 = keys.begin();
std::vector<int>::const_iterator end1 = keys.end();
std::vector<std::string>::const_iterator beg2 = values.begin();
std::vector<std::string>::const_iterator end2 = values.end();
map_t my_map;
// simply iterate over...
std::transform(
boost::make_zip_iterator(
boost::make_tuple(beg1, beg2)
),
boost::make_zip_iterator(
boost::make_tuple(end1, end2)
),
std::inserter(my_map, my_map.end()),
adapt_tuple
);
std::cout << "size of map: " << my_map.size() << std::endl;
return 0;
}
答案 4 :(得分:0)
假设,你将忽略额外的(vect1的大小!= vect2的大小),这可能是一个解决方案:
map<T1, T2> target; //vector<T1> vect1, vector<T2> vect2;
vector<T1>::iterator it1 = vect1.begin();
vector<T2>::iterator it2 = vect2.begin();
while(it1 != vect1.end() && it2 != vect2.end())
{
target.insert(std::make_pair(*it1, *it2));
it1++;it2++;
}
编辑:感谢Nim指出* it1的事情。