【问题标题】:how does the stl's multimap insert respect orderings?stl 的多图如何插入尊重排序?
【发布时间】:2009-10-20 15:01:12
【问题描述】:

我有一些带有整数索引的数据。我不断生成新数据,这些新数据需要添加到我拥有的数据集合中,按该索引排序,同时我希望能够轻松地开始数据并遍历它。这听起来像 std::multimap 正是我所需要的。

但是,我还需要按照插入顺序保留具有相同索引的数据,在这种情况下,这意味着当我遍历数据时,我会先获取较早的数据,然后再获取较晚的数据。

multimap 会这样做吗?

我没有找到任何保证是这种情况。在 sgi 手册中,我没有看到任何提及是否。我在 gcc 4.3.4 实现上进行了尝试,对于一些有限的测试用例似乎是正确的,但我当然想知道标准是否要求这样做,我可以依赖这个事实。

编辑:为了更清楚地回应一些答案,我希望数据首先按(非唯一)索引排序,然后按插入时间排序。我曾希望也许第二部分可以免费提供多地图,但似乎没有。

【问题讨论】:

    标签: c++ multimap


    【解决方案1】:

    似乎新标准 (C++11) 改变了这一点:

    其键比较等效的键值对的顺序为插入顺序,不会改变。[cppreference]

    不过我在犹豫是否要使用它,因为在将标准库修改为与 C++11 兼容时,这似乎是一个很容易被忽略的细节,而且如果你的编译器的库无法实现,这种细节会默默地导致错误正确。

    【讨论】:

    • 嗯,也不是不能在实现中检查。
    【解决方案2】:

    除非我遗漏了什么,否则该标准不提供任何此类保证。

    最明显的解决方法是包含一个序列号作为辅助键。例如,在您的类中包含一个静态无符号长整数,并且每次创建要插入到多重映射中的对象时,将其当前值放入您的对象中,然后递增它。在对象的比较函数中,如果您当前用作键的数据比较相等,请使用该计数器作为排序的决定因素。请注意,在这种情况下,每个键都是唯一的,因此您可以使用映射而不是多映射。

    【讨论】:

      【解决方案3】:

      如果您不想采用Jerry Coffin 提供的解决方法,Boost multi_index 支持您正在尝试做的事情。

      【讨论】:

      • 举个例子怎么样?
      【解决方案4】:

      如果我没听错 - 你需要按某个键排序的数据。每当您使用相同的 key 插入 2 个东西时,您都需要按照插入的顺序检索它们。

      如果是这种情况,那么你必须看看你的多图的实现。取决于它如何处理使用相同密钥的多次插入的情况,它可能有也可能没有这个保证。我猜这个标准没有提供这种保证,因为它会限制非常特殊情况的实现。

      另一种方法是使用 Map(而不是 Multi)并创建复合键。该键由您选择的普通键和一个不断增加的计数器组成。相比之下,对于相等的键,插入编号使键唯一。通过这种方式,您可以强制使用唯一键和相同“普通”键的顺序(我希望这是可以理解的)。

      我猜最后一种方法是最容易实现的。


      选项:(不推荐)

      有了这个保证,您总是可以使用自制的数据结构。我会选择带有向量的树(例如红黑或 AVL)来保存插入的数据。在迭代时,您必须找到节点,转到向量并迭代它的内容。每当您完成向量时,您都会继续下一个节点。

      【讨论】:

        【解决方案5】:

        不,不会的。如果你愿意,你应该使用像向量这样的“序列容器”。例如,您可以使用 std::pairs 加载向量?

        【讨论】:

          【解决方案6】:

          听起来你需要多地图...

          但是,我还需要数据 相同的索引按顺序保存 它被插入,在这种情况下 意思是当我遍历 我得到的数据到较早的数据 在后面的数据之前。

          它将按照索引的顺序。如果随着您插入更多项目而索引随着时间的推移而增加,那么是的,因为您的索引的性质,“较早”的数据将首先出现。

          否则,不行。您可以将两个多图保留到相同的数据。一个按索引顺序保存,另一个按插入时间顺序保存:

          std::multimap<index, T*> orderedByIndex;
          std::multimap<time, T*> orderedByInsertionTime;
          

          让您能够双向迭代地图。

          编辑我读这篇文章的意思是您有时希望按索引迭代或有时按插入时间迭代,但如果您的意思是第一个索引然后插入时间,请参阅上面的答案。)

          【讨论】:

            【解决方案7】:

            当您检索信息时,属于同一键的元素由lower_boundupper_bound 函数排序,因此您不能保证您将访问(通过equal_range)中的元素插入它们的顺序。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2014-02-01
              • 1970-01-01
              • 2019-09-13
              • 1970-01-01
              • 2019-09-23
              • 1970-01-01
              • 2021-06-07
              • 2010-12-25
              相关资源
              最近更新 更多