2009-03-26 7 views
17

Каков наилучший способ в C++ скопировать пару с карты на вектор? Я делаю это, чтобы впоследствии сортировать вектор.C++ как скопировать карту в вектор

+2

Очень расплывчатый вопрос – camh

+1

Карты сортированы. Вы должны указать, хотите ли вы сортировать другой параметр или с помощью другого ключа. Еще один вопрос - ответ на вопрос: не надо. –

ответ

19

Это должно делать то, что вы хотите:

#include <iostream> 
#include <vector> 
#include <map> 
#include <algorithm> 
#include <iterator> 

using namespace std; 

bool cmp(const pair<int, int> &p1, const pair<int, int> &p2) 
{ 
    return p1.second < p2.second; 
} 

int main() 
{ 
    map<int, int> m; 
    for(int i = 0; i < 10; ++i) 
     m[i] = i * -i; 

    vector<pair<int, int> > v; 
    copy(m.begin(), m.end(), back_inserter(v)); 

    sort(v.begin(), v.end(), cmp); 

    for(int i = 0; i < v.size(); ++i) 
     cout << v[i].first << " : " << v[i].second << endl; 
    return 0; 
} 
2

A map хранит пару - ключ и значение. Какую часть вы хотите скопировать? Или, вы хотите скопировать оба на два отличных vector?

Я хочу скопировать оба. Как только это будет сделано, мне нужно выяснить, как сортировать вектор по значению в секунду.

template <class V> 
struct sort_by_val { 
    bool operator()(V const& l, V const& r) { 
     return // ... 
    } 
}; 

vector<pair<K, V> > outv(map.begin(), map.end()); 

sort(outv.begin(), outv.end(), sort_by_val()); 
+0

Я хочу скопировать оба. Как только это будет сделано, мне нужно выяснить, как отсортировать вектор по значению * second * в паре. –

+0

+1, прозрачное и простое решение. @Jack: вы должны поместить информацию в свой комментарий в главный вопрос, так как это очень важно. это помешало бы всем упомянуть, что карты уже отсортированы по их первым элементам. –

6

Если вы используете зЬй :: карта, это уже отсортирован по ключу. Просто создайте итератор и проведите по карте с начала() до конца(), и все готово.

Если вы хотите отсортировать что-то, кроме ключа карты, вы можете использовать один и тот же итератор и нажимать копию каждого элемента на свой вектор, когда вы перебираете карту.

+0

Может быть еще проще: вы можете указать компаратор в CTor карты. – foraidt

25
vector<pair<K,V> > v(m.begin(), m.end()); 

или

vector<pair<K,V> > v(m.size()); 
copy(m.begin(), m.end(), v.begin()); 

copy() в <algorithm>.

+2

Этот, кажется, более элегантный и простой – Ram

+1

Да, это лучший, особенно первый. Несколько поясняющих комментариев: если у вас есть 'typedef std :: map MapType', вы не можете объявить вектор' vector 'as value_type is' pair ', который не имеет оператора = и не может скопированы в вектор.Кроме того, во втором примере очень важно передать размер вектора сначала (либо через конструктор, либо в резерв), поскольку копия не будет выделять пространство в векторе по мере добавления элементов, и есть большая вероятность, что вы нажмете на конец исходного выделения вектора. –

+1

'copy (m.begin(), m.end(), v.begin());' дал мне ошибку сегментации. Просто говорю. – yasith

2

Предполагая, что вы хотите скопировать ключ и значение:

std::map<Foo, Bar> m; 


// Map gets populated 
// (...) 


// Copying it to a new vector via the constructor 
std::vector<std::pair<Foo, Bar>> v(m.begin(), m.end()); 


// Copying it to an existing vector, erasing the contents 
v.assign(m.begin(), m.end()); 

// Copying it to the back of an existing vector 
v.insert(v.end(), m.begin(), m.end()); 
+0

Это последнее неверное. Возможно, вы имеете в виду v.insert (v.rbegin(). Base(), m.begin(), m.end()); ? – wilhelmtell

+0

whihelmtell - почему вы думаете, что это неправильно? Я просто попробовал - все отлично. –

+0

Подумайте об этом: v.rebegin(). Base() возвращает тот же самый итератор, что и v.end() –

2

Если ваша цель просто отсортировать по типу вместо ключа , вы можете посмотреть на Boost::Bimap. Он позволяет вам получить доступ к обеим частям пары карт в виде ключей. Предположительно, вы могли бы перебирать его по порядку второго ключа так же легко, как и первый.

0

Вы можете использовать другую карту (или набор) и использовать преобразование для сортировки, как вы вставите:

#include <map> 
#include <algorithm> 

typedef std::map<unsigned int, signed char> MapType1; 
typedef std::map<MapType1::mapped_type, MapType1::key_type> MapType2; 

struct SwapPair 
{ 
    MapType2::value_type operator()(MapType1::value_type const & v) 
    { 
    return std::make_pair (v.second, v.first); 
    } 
}; 

int main() 
{ 
    MapType1 m1; 
    for(int i = 0; i < 10; ++i) 
    m1[i] = i * -i; 

    MapType2 m2; 
    std::transform (m1.begin() 
     , m1.end() 
     , std::inserter (m2, m2.end()) 
     , SwapPair()); 
} 

Я забыл добавить, что если вам нужно сделать, это много, то это могло бы быть лучше просто для того, чтобы использовать ускорение multi-index контейнер.

 Смежные вопросы

  • Нет связанных вопросов^_^