stl的multimap如何插入尊重排序?

时间:2009-10-20 15:01:13

标签: c++ multimap

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

但是,我还需要按照插入顺序保存具有相同索引的数据,在这种情况下意味着当我遍历数据时,我会在之后的数据之前找到更早的数据。

multimap会这样做吗?

我没有找到任何保证,就是这种情况。在sgi手册中,我没有看到是否提及。我在gcc 4.3.4实现上试过它,对于一些有限的测试用例来说似乎是真的,但当然我想知道标准是否要求这个并且我可以依赖这个事实。

编辑:为了更清楚地回答一些答案,我希望数据首先按(非唯一)索引排序,然后按插入时间排序。我原本希望第二部分可以免费使用multimap,但似乎没有。

7 个答案:

答案 0 :(得分:34)

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

  

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

我在使用它时犹豫不决,因为在将标准库修改为C ++ 11兼容时,这似乎是一个容易被忽视的细节,如果编译器的库无法实现,那么这种细节会无声地导致错误正常。

答案 1 :(得分:8)

除非我遗漏了某些内容,否则该标准不提供此类保证。

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

答案 2 :(得分:4)

如果您不想采用multi_index提供的解决方法,

Boost Jerry Coffin支持您要执行的操作。

答案 3 :(得分:2)

如果我找对你 - 你需要按一些键排序的数据。每当您使用相同的密钥插入2个内容时,您需要按插入顺序检索它们。

如果是这种情况,那么你必须看看你的多图的实现。根据它如何处理具有相同键的多次插入的情况,它可能有也可能没有这种保证。我想标准不提供这种保证,因为它会限制一个非常特殊情况的实施。

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

我想最后一种方法最容易实现。


选项:(不可取)

您可以随时使用此保证来获取自制数据结构。我会去一个树(例如红黑或AVL),用一个向量来保存插入的数据。在迭代中,您必须找到节点,转到向量并迭代它的内容。无论何时完成向量,都可以继续使用下一个节点。

答案 4 :(得分:1)

不,不会。如果你想要,你应该像矢量一样使用“序列容器”。你可以加载带有std :: pairs的向量吗?

答案 5 :(得分:1)

听起来好像你需要的是multimap ......

  

但是,我还需要数据   相同的索引保持在顺序中   它插入了,在这种情况下   这意味着当我迭代时   我得到的数据是早先的数据   在后来的数据之前。

它将按索引的顺序排列。如果在插入更多项目时索引随着时间的推移而增加,那么由于索引的性质,是的,“早期”数据将首先出现。

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

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

让您能够双向迭代地图。

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

答案 6 :(得分:1)

当您检索信息时,属于同一密钥的元素会被lower_boundupper_bound函数强制执行,因此您无法保证可以访问({{3} })元素按插入顺序排列。