создание карты из двух векторов - PullRequest
5 голосов
/ 09 февраля 2011

Если у меня есть два вектора stl vect1, vect2 и я хочу создать из них карту, то первый элемент из vect1 будет соответствовать первому элементу в vect2 и так далее.Как я могу сделать это самым простым способом?

Ответы [ 5 ]

8 голосов
/ 09 февраля 2011
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];
6 голосов
/ 09 февраля 2011

Вот решение, которое использует стандартные библиотечные функции (и лямбды C ++ 0x).

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 ().

4 голосов
/ 09 февраля 2011

Мы будем использовать версию std :: transform , которая принимает 2 входные последовательности.(Не так хорошо известно, что он выглядит как тот, который занимает одну последовательность).

Вы можете передать 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&> );

IЯ протестировал код, и он прекрасно компилируется с GNU 4.3.2

(я также тестировал сейчас с C ++ 11. Он работает, когда я изменил make_pair, чтобы принимать int const & вместо int).1012 * Если две входные последовательности имеют разную длину, будет хорошо, если первая короче, а более поздние элементы во второй последовательности будут игнорироваться.Если первое длиннее, оно будет вызывать неопределенное поведение.

1 голос
/ 09 февраля 2011

Вот небольшая вариация, в которой используется zip_iterator

boost 1007 *

хорошо, вот более простая версия с использованием 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;
}
0 голосов
/ 09 февраля 2011

при условии, что вы собираетесь игнорировать дополнительные (размер 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++;
}

РЕДАКТИРОВАТЬ: Спасибо Ним за указание * it1 вещь.

...