22

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

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

多图这样做吗?

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

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

4

7 回答 7

43

It seems the new standard (C++11) changed this:

The order of the key-value pairs whose keys compare equivalent is the order of insertion and does not change.[cppreference]

I'm hesitating to use it though, as this seems like a detail easily overlooked when modifying the standard library to be C++11 compliant and it's the sort of detail that will silently cause errors if your compiler's library failed to implement properly.

于 2012-11-12T02:23:56.330 回答
8

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

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

于 2009-10-20T15:12:02.800 回答
4

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

于 2009-10-20T15:28:18.220 回答
3

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

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

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

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


选项:(不推荐)

You can always go for a self-made datastructure with this guarantee. I'd go for a Tree (Red-Black or AVL for example) with a vector to hold the inserted data. On iteration you have to find the node, go to the vector and iterate on it's content. Whenever you finish with the vector, you continue with the next node.

于 2009-10-20T15:31:36.653 回答
1

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

于 2009-10-20T15:12:41.043 回答
1

听起来多图是您所需要的...

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

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

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

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

使您能够以两种方式迭代地图。

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

于 2009-10-20T15:13:01.403 回答
1

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

于 2009-10-20T15:19:21.663 回答