C ++中简单高效的容器,具有map和list容器的特性

时间:2010-11-01 15:55:27

标签: c++ map linked-list containers

我正在寻找一个既能享受地图容器又能享受列表容器优势的C ++容器。

地图我希望维护的容器优势:

  • O(log(n))access
  • operator []易用性
  • 稀疏性

列表我希望维护的容器优势:

  • 订购商品之间的订单
  • 能够轻松遍历列表更新:按基于键或值的排序顺序

一个简单的示例应用程序是保存某些有效日期(业务日期,假日,其他一些重要日期......)的列表,一旦给定特定日期,您可以立即找到它“地图样式”和然后找到下一个有效日期“列表样式”。

8 个答案:

答案 0 :(得分:8)

std::map已经是一个已排序的容器,您可以按顺序迭代所包含的项目。但它只提供O(log(n))访问。

std::tr1::unordered_map(或C ++ 0x中的std::unordered_map)具有O(1)访问权限但未排序。

你真的需要O(1)访问吗?您必须使用大型数据集并对O(log(n))进行许多查找,但速度不够快。

如果O(log(n))足够,std::map会提供您要求的所有内容。

答案 1 :(得分:5)

如果您不考虑稀疏性质,可以查看Boost Multi-Index library。对于稀疏性质,您可以查看Boost Flyweight library,但我想您必须自己加入这两种方法。请注意,您的要求通常是矛盾的,很难实现。例如,O(1)和项目之间的顺序很难有效维护。

答案 2 :(得分:3)

地图通常以树形式实现,因此具有对数查找时间,而不是O(1),但听起来您需要一个已排序的关联容器。哈希映射有O(1)最佳情况,O(N)最坏情况,所以也许这就是你的意思,但它们没有排序,我认为它们还不是标准库的一部分。

在C ++标准库中,mapsetmultimapmultiset是关联容器的排序,但您必须放弃O(1)外观提出要求。

答案 3 :(得分:3)

根据Stroustrup,地图的[]运算符是O(log(n))。如果你用列表尝试这样的东西,那比你得到的O(n)要好得多,但绝对是而不是O(1)。为[]运算符提供的唯一容器是vector。

除此之外,您已经可以使用地图完成所有列表。迭代器可以正常工作。所以,如果我是你,我会坚持使用地图。

答案 4 :(得分:2)

这一个怎么样:所有日期都存储在std::list<Date>中,但是您可以使用辅助结构stdext::hash_map<Date, std::list<Date>::iterator>进行查找。一旦你有了列表的迭代器,就可以访问下一个元素了。在您的STL实施中,它可以是std::tr1::unordered_map而不是stdext::hash_map,并且还有boost::unordered_map

答案 5 :(得分:2)

  
      
  • 订购商品之间的订单
  •   
  • 能够轻松浏览列表
  •   

地图已经同时执行。它们是有序的,所以你从begin()开始并遍历直到你到达end()。当然,你可以从任何地图迭代器开始;您可能会发现map的find,lower_bound和相关方法很有用。

答案 6 :(得分:2)

您可以将数据存储在列表中,并为列表中的迭代器提供映射,使您能够找到实际的列表元素本身。这种事情是我经常用于LRU容器的东西,我想要一个列表,因为我需要将被访问的元素移动到最后以使其成为最近访问的。您可以使用splice函数执行此操作,并且从2003标准开始,只要将迭代器保存在同一列表中,它就不会使迭代器失效。

答案 7 :(得分:1)

您永远不会找到满足O(log n)访问权限和有序性质的容器。原因是如果订购了一个容器,那么它本身就必须支持一个任意的订单。这就是有序的性质意味着:你可以准确地确定任何元素的位置。所以要找到任何元素,你必须猜测它在哪里。它可以在任何地方,因为你可以把它放在任何地方!

请注意,有序序列与已排序序列不同。排序的性质意味着任何两个元素之间存在一个特定的排序关系。有序的性质意味着元素之间可能存在多个排序关系。