按键排序std :: unordered_map

dev*_*ull 14 c++ sorting unordered-map

如何unordered_map按顺序排序?我需要打印unordered_map按键排序.

ron*_*nag 24

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;
Run Code Online (Sandbox Code Playgroud)

  • 并且不要忘记,如果您不关心保留初始容器中的元素,可以使用`make_move_iterator` 将元素移动到新容器中:`std::map&lt;int, int&gt;ordered(std: :make_move_iterator(unordered.begin()), std::make_move_iterator(unordered.end()));` (2认同)

Dav*_*men 20

另一种解决方案是构造键的矢量,对矢量进行排序,并根据该排序的矢量进行打印.这将比从有序地图构造地图的方法快得多,但也将涉及更多代码.

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] << ' ';
}
Run Code Online (Sandbox Code Playgroud)

  • 如果使用向量和`std :: sort`而不是列表,它会更快. (10认同)
  • 如果您保留具有所需长度的矢量(如果必须使用push_back),甚至还要快一点 (2认同)

Xeo*_*Xeo 12

确定需要这个吗?因为那是不可能的.An unordered_map是一个哈希容器,即密钥是哈希的.在容器内部,它们与外部的表示不同.即使这个名字暗示你也无法对它进行排序.它的标准来选择一个哈希容器之一:你不是需要一个特定的顺序.

如果你这样做,那就正常了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>());
}
Run Code Online (Sandbox Code Playgroud)

Ideone上的示例.
请注意,在C++ 0x中,您可以使用默认模板参数将一个函数替换为两个重载:

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));
}
Run Code Online (Sandbox Code Playgroud)

  • 您可以使用`std :: ostream_iterator`和`std :: copy`而不是您自己的`streamer` thingie. (2认同)