21

unordered_mapキーで並べ替えるにはどうすればよいですか?unordered_mapキーでソートして印刷する必要があります。

4

5 に答える 5

37
std::unordered_map<int, int> unordered;

std::map<int, int> ordered(unordered.begin(), unordered.end());
for(auto it = ordered.begin(); it != ordered.end(); ++it)
     std::cout << it->second;
于 2011-06-02T09:31:49.150 に答える
27

別の解決策は、キーのベクトルを作成し、そのベクトルを並べ替えて、その並べ替えられたベクトルごとに印刷することです。これは、順序付けられたマップからマップを作成するアプローチよりもかなり高速ですが、より多くのコードが必要になります。

std::unordered_map<KeyType, MapType> unordered;
std::vector<KeyType> keys;

keys.reserve (unordered.size());
for (auto& it : unordered) {
    keys.push_back(it.first);
}
std::sort (keys.begin(), keys.end());
for (auto& it : keys) {
    std::cout << unordered[it] << ' ';
}
于 2011-06-02T09:59:39.240 に答える
13

これが必要です?それは不可能だからです。Anunordered_mapはハッシュコンテナです。つまり、キーはハッシュされます。コンテナの内側では、外側と同じ表現はありません。名前でさえ、あなたがそれを分類することができないことを意味します。これは、ハッシュコンテナを選択するための基準の1つです。特定の順序は必要ありません。

そうした場合、通常のを取得しますmap。キーは、厳密に弱い順序で自動的に並べ替えられます。別の種類が必要な場合は、独自のコンパレータを作成してください。

並べ替えて印刷するだけでよい場合、以下は非効率的かもしれませんが、それでも保持したい場合に得られるものと同じくらい近いですunordered_map

#include <map>
#include <unordered_map>
#include <algorithm>
#include <iostream>
#include <functional>

struct map_streamer{
  std::ostream& _os;

  map_streamer(std::ostream& os) : _os(os) {}

  template<class K, class V>
  void operator()(std::pair<K,V> const& val){
    // .first is your key, .second is your value
    _os << val.first << " : " << val.second << "\n";
  }
};

template<class K, class V, class Comp>
void print_sorted(std::unordered_map<K,V> const& um, Comp pred){
  std::map<K,V> m(um.begin(), um.end(), pred);
  std::for_each(m.begin(),m.end(),map_streamer(std::cout));
}

template<class K, class V>
void print_sorted(std::unordered_map<K,V> const& um){
  print_sorted(um, std::less<int>());
}

Ideoneの例
C ++ 0xでは、2つのオーバーロードをデフォルトのテンプレート引数を持つ1つの関数に置き換えることができることに注意してください。

template<class K, class V, class Comp = std::less<int> >
void print_sorted(std::unordered_map<K,V> const& um, Comp pred = Comp()){
  std::map<K,V> m(um.begin(), um.end(), pred);
  std::for_each(m.begin(),m.end(),map_streamer(std::cout));
}
于 2011-06-02T09:28:05.423 に答える
3

Davidの答えと同様に、std::set最初にキーを並べ替えるために使用できます。

std::unordered_map<int, int> unordered;
std::set<int> keys;
for (auto& it : unordered) keys.insert(it.first);
for (auto& it : keys) {
    std::cout << unordered[it] << ' ';
}
于 2018-10-21T00:21:45.390 に答える
0

ベクトルを使用してキーと値のペアを格納し、それらをベクトルで並べ替えて、最後にマップに戻すことができます。

#include <iostream>                                 
#include <unordered_map>                                 
#include <algorithm>                                 
#include <vector>                                 

using namespace std;                                

int main(){                                
    unordered_map<string, int> sdict = {{"hello", 11 }, {"world", 52}, {"tommy", 3}};               
    unordered_map<string, int> resdict;          

    vector<pair<string, int>> tmp;
    for (auto& i : sdict)                                         
        tmp.push_back(i);                                

    for (auto& i : sdict)       
        cout <<  i.first << " => " << i.second << endl;  

    // sort with descending order.
    sort(tmp.begin(), tmp.end(),                                   
    [&](pair<string, int>& a, pair<string, int>& b) { return a.second < b.second; });

    for (auto& i : tmp)                          
    {                           
        resdict[i.first] = i.second;                   
    }                                

    cout << "After sort." << endl;   
    for (auto& i : resdict)     
        cout <<  i.first << " => " << i.second << endl;           
    return 0;                                              

}                                            

次のコマンドでコンパイルします。

g++ --std=c++11 test_sort_ordered_map.cpp

結果は次のとおりです。

tommy => 3
hello => 11
world => 52
After sort.
world => 52
hello => 11
tommy => 3
于 2018-12-27T03:34:04.607 に答える