Как я могу отсортировать карту по ее .second параметру [дубликат]

21
задан amitlicht 16 March 2010 в 10:07
поделиться

6 ответов

Вы не можете отсортировать карту по ее значениям из-за реализации карты.

Если вы хотите передать элементы на карте в таком отсортированном порядке, вам нужно сначала выгрузить содержимое карты в вектор (скажем) и отсортировать этот вектор:

template <typename T1, typename T2>
struct less_second {
    typedef pair<T1, T2> type;
    bool operator ()(type const& a, type const& b) const {
        return a.second < b.second;
    }
};

map<string, int> mymap;
// …

vector<pair<string, int> > mapcopy(mymap.begin(), mymap.end());
sort(mapcopy.begin(), mapcopy.end(), less_second<string, int>());

Или, альтернативно, просто скопируйте значения из map, оставив ключи, и отсортируйте полученный вектор напрямую.

28
ответ дан 29 November 2019 в 20:32
поделиться

Вы не можете сделать это автоматически. std :: map использует первое значение (nomen omen 'key') для сортировки содержимого.

Вместо этого вы можете использовать boost :: multi_index_container .

4
ответ дан 29 November 2019 в 20:32
поделиться

Вы можете скопировать все значения в вектор и отсортировать его.

#include <algorithm>
#include <map>
#include <vector>

int get_second( pair<string, int> i ){ return i.second; }

int main(int argc, char* argv){
  map<string, int> m;
  m["tt"] = 2;
  m["rr"] = 1;
  m["ee"] = 3;

  vector<int> v( m.size() );
  transform( m.begin(), m.end(), v.begin(), get_second );
  sort( v.begin(), v.end() );
  for (int i=0; i<v.size(); i++) cout << v[i] << endl;
}
6
ответ дан 29 November 2019 в 20:32
поделиться

Вы не можете отсортировать карту, это ассоциативный контейнер, а не последовательный, и связанные контейнеры сортируются в некотором внутреннем порядке.

Если вы хотите распечатать только значения int , вы можете поместить их в std :: vector , отсортировать вектор и распечатать значения.

1
ответ дан 29 November 2019 в 20:32
поделиться

Если вам нужно сделать это несколько раз, может быть более эффективным сохранить два отдельных контейнера, например ваша карта и отсортированный контейнер, такой как set или multiset , для хранения отсортированных целых чисел, вместо того, чтобы создавать контейнер и сортировать его на лету. Но тогда вы должны поддерживать их синхронизацию, что может стать неприятным. Вы можете инкапсулировать это, обернув их в класс, или еще лучше использовать boost :: multi_index_container .

3
ответ дан 29 November 2019 в 20:32
поделиться

Вместо использования vector, я бы предпочел просто скопировать их в set:

#include <map>
#include <set>
#include <string>
#include <iostream>
#include <iterator>

using namespace std;

set<int> map2set(map<string, int> const& m) {
 set<int> r;
 for (map<string, int>::const_iterator b = m.begin(), e = m.end(); b != e; ++b)
   r.insert(b->second);
 return r;
}

int main() {
 map<string, int> m;
 m.insert(make_pair("hello", 42));
 m.insert(make_pair("world", 24));
 set<int> s = map2set(m);
 copy(s.begin(), s.end(), ostream_iterator<int>(cout, "\n"));
}
0
ответ дан 29 November 2019 в 20:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: