std :: list with std :: map properties?

时间:2009-01-08 02:06:26

标签: c++ stl list maps

基本上,我想要一个std :: list但是有std :: map属性,比如find(),我是否真的需要遍历每个列表条目才能找到我需要的东西?

9 个答案:

答案 0 :(得分:15)

如果你想要std :: map的属性,为什么不使用std :: map?它比循环遍历每个元素更有效。

答案 1 :(得分:11)

Checkout Boost.MultiIndex,比使用带指针的多个容器更容易,更有效。

答案 2 :(得分:9)

如果你想要一个容器:

1)插入顺序并不重要(这是一个清单)
2)搜索速度是。

然后使用

的std ::设置<>

答案 3 :(得分:3)

使用std::findstd::find_if查找某些迭代器范围内某个值的第一个位置。

答案 4 :(得分:3)

如果您担心搜索时间但希望保留订单,则可能会保留两个具有相同数据的容器。

答案 5 :(得分:2)

std :: list的目的是找不到/搜索。这就是std :: map的用途。列表非常适合插入,提取,移动和使用排序算法。如果您只需要存储数据并随机查找它,那么请使用地图。如果要构建存储数据的方式和位置,请使用列表。

答案 6 :(得分:1)

选项1

听起来你想要的是单个元素的地图,而不是对的地图。使用std::set<T>,这是一个实现为std::map<T,void>的适配器。这意味着你的所有元素都是独一无二的;也就是说,容器中没有重复项。它还暗示您的元素不会严格排序;也就是说,您不能在任何给定时间依赖任何元素的位置。然后,您可以使用find()的{​​{1}}成员函数,该函数将以对数时间快速搜索元素。

选项2

如果您想要的是一个能够快速访问最小或最大元素的容器,那么您可以将std::set<T>与您选择的容器std::priority_queue<T,C>一起使用。如果未指定,则使用的默认容器为Cstd::vector<T>使用std::priority_queue<T>make_heap()push_heap()算法,因此需要底层容器支持随机访问迭代器;在这种情况下,pop_heap()是不够的。使用std::list<T>成员函数以恒定时间访问“第一个”(最大或最小)元素。使用top()push()成员函数推送和弹出第一个元素,这些函数以对数时间运行(实际上是2 * log(n),因为它们需要搜索以及冒泡)。 / p>

选项3

如果您想要的只是一个包含对的列表,只需将其声明为:

pop()

这只会给出一个链接列表,其中包含任何其他链接列表的限制和优点,但会像地图一样保存对。因此,您将使用标准算法来操作列表。您可能需要将特殊函数或仿函数传递给具有此列表的算法,以取消引用该对中的键或值。

如果您只想搜索列表中的项目而不考虑效率,则可以在O(n)时间内使用std::list<std::pair<T> > the_list; 算法执行此操作。这正是该算法的用途,为任何容器提供线性时间搜索功能,而不是比这更好。这是我们使用未排序的数组或向量,列表等。它应该是你的最后的手段,因为它可能比替代品慢得多,虽然它本身就慢。如果你不经常搜索,如果你知道元素在第一个迭代器附近,如果容器很小,没有任何更快的替代品等,则使用这种方法。

答案 7 :(得分:0)

@obecalp有一个很好的答案。提升MultiIndex是一个很好的建议。 @Bklyn:是一个“非常愚蠢”的问题。

答案 8 :(得分:0)

我需要完全相同的东西,所以我写了一些列表和地图的组合。我称之为map_list&lt;&gt;和hash_map_list&lt;&gt ;.基本上,我把源代码带到了xmap.h和xlist.h,并将两者结合起来制作xmap_list.h。此类的工作方式是将键存储在给定的映射中,但与指向包含该值的节点的指针配对。此节点包含一个指向地图的迭代器。节点保存在单独的链表中。以这种方式,您可以像使用map类一样使用find函数,但您也可以按照插入它们的顺序迭代元素,就像列表类一样。您甚至可以像在列表中一样迭代密钥。我没有实现每个最后的等效列表函数,但是大多数你最常使用的函数都存在(例如,我不处理自定义分配器,尽管你可以自己轻松添加它)。它看起来像列表&lt;&gt;使用find()函数。

对于我为此编写的项目,我最终最终转向boost :: multi_index,但我仍然使用上面的map_list&lt;&gt;我什么时候上课,因为它更轻量级,更接近std :: list&lt;&gt;接口

我没有在任何地方上传代码,但如果我看到有人在此答案中添加了评论,我会尝试将其发布到某处,并在此处记下该位置。