【问题标题】:Keep the order of unordered_map as we insert a new key插入新键时保持 unordered_map 的顺序
【发布时间】:2016-01-28 05:33:24
【问题描述】:

我使用以下代码将元素插入到unordered_map

    myMap.insert(std::make_pair("A", 10));
    myMap.insert(std::make_pair("B", 11));
    myMap.insert(std::make_pair("C", 12));
    myMap.insert(std::make_pair("D", 13));

但是当我使用这个命令来打印密钥时

for (const auto i : myMap)
{
    cout  << i.first << std::endl;
}

它们与我插入它们的顺序不同。

是否可以保留订单?

【问题讨论】:

  • unordered_map 中的“无序”部分应该告诉你一些事情......
  • 没有。它被称为“无序”是有原因的。如果您需要维护插入顺序,则说明您选择了不合适的数据结构。使用成对的向量,或类似的东西。
  • @Yuushi std::map 维护字典顺序,而不是插入顺序。
  • @IgorTandetnik 为什么是“字典式”? Compare模板参数定义键和枚举的顺序。
  • @c-smile 我承认我简化了。我觉得,一个学究式的正确陈述太长了,只会掩盖我试图表达的观点。

标签: c++ c++11


【解决方案1】:

不,这是不可能的。

使用std::unordered_map 并不能保证元素顺序。

如果您想保持元素按地图键排序(从您的示例中可以看出),您应该使用std::map

如果您需要保留有序对的列表,您可以使用std::vector&lt;std::pair&lt;std::string,int&gt;&gt;

【讨论】:

    【解决方案2】:

    不具有无序关联数据结构。但是,其他数据结构保持顺序,例如 std::map 保持数据按其键排序。如果您稍微搜索一下 Stackoverflow,您会发现许多针对具有快速基于键的查找和有序访问的数据结构的解决方案,例如using boost::multi_index.

    如果只是向容器添加值,然后按插入顺序取出它们,那么您可以使用模拟队列的东西,例如std::dequeue。只需push_back 添加一个新值,pop_front 删除最旧的值。如果不需要从容器中删除值,则只需使用 std::vector

    【讨论】:

      【解决方案3】:

      非常常见的请求,没有太多干净、简单的解决方案。但他们在这里:

      1. 大库:https://www.boost.org/doc/libs/1_71_0/libs/multi_index/doc/tutorial/index.html 使用唯一索引 std::string(还是 char?)和有序索引来保留顺序。
      2. 使用 2 个 STL 容器自己编写:使用 std::unordered_map(或 std::map,如果您还想要排序的键顺序遍历)和一个向量的组合来保留排序的顺序。有几种设置方法,具体取决于您的键/值的类型。通常是映射中的键和向量中的值。那么地图是 map ,其中 int 指向向量中的元素,因此指向值。

      我可能会玩一个简单的包装模板,将 2 个 STL 容器捆绑在一起,稍后再将其发布到这里...

      我已经为review here 提交了一个概念证明:

      最后我使用 std::list 来存储订单,因为我想要有效的删除。但是,如果您想按插入顺序进行随机访问,您可以选择 std::vector 。

      我使用了一个 Pair 指针列表来避免重复的密钥存储。

      【讨论】:

        猜你喜欢
        • 2010-12-09
        • 1970-01-01
        • 1970-01-01
        • 2021-08-19
        • 1970-01-01
        • 2017-01-14
        • 2013-10-03
        • 1970-01-01
        • 2011-12-18
        相关资源
        最近更新 更多