【发布时间】:2014-03-05 16:01:16
【问题描述】:
在以下示例中尝试编写 std::unordered_map 的 std::string 键时,键的写入顺序与初始化列表给出的顺序不同:
#include <iostream>
#include <unordered_map>
class Data
{
typedef std::unordered_map<std::string, double> MapType;
typedef MapType::const_iterator const_iterator;
MapType map_;
public:
Data(const std::initializer_list<std::string>& i)
{
int counter = 0;
for (const auto& name : i)
{
map_[name] = counter;
}
}
const_iterator begin() const
{
return map_.begin();
}
const_iterator end() const
{
return map_.end();
}
};
std::ostream& operator<<(std::ostream& os, const Data& d)
{
for (const auto& pair : d)
{
os << pair.first << " ";
}
return os;
}
using namespace std;
int main(int argc, const char *argv[])
{
Data d = {"Why", "am", "I", "sorted"};
// The unordered_map speaks like Yoda.
cout << d << endl;
return 0;
}
我希望看到“我为什么要排序”,但我得到了类似 Yoda 的输出:
sorted I am Why
阅读unordered_maphere,我看到了这个:
在内部,元素不按任何特定顺序排序,而是组织成桶。元素放入哪个桶完全取决于其键的哈希值。这允许快速访问单个元素,因为一旦计算哈希,它指的是元素被放入的确切存储桶。
这就是为什么元素的排序方式与初始化列表中的不同吗?
当我希望以与初始值设定项列表相同的方式对键进行排序时,我应该使用什么数据结构?我应该在内部保留一个字符串向量以某种方式保存参数顺序吗?可以通过选择特定的散列函数以某种方式关闭存储桶组织吗?
【问题讨论】:
-
“当我希望以与初始化列表相同的方式对键进行排序时,我应该使用什么数据结构?” 名称中可能没有
unordered. ;-) -
好吧,我已经在使用
unordered_map,它的哈希函数仍然会重新排列键。 -
试试普通的
map。这行得通吗? -
@graham.reeds,没有,因为在这种情况下,键是使用字符串比较进行排序的。
-
听起来像是 Boost.Multiindex 的工作。可以根据上下文以多种方式访问多索引容器。例如,您可以将散列索引容器(用于基于键的查找)与有序索引容器(用于有序、顺序查找)混合。
标签: c++ c++11 unordered-map