是否有sorted_vector类,它支持insert()等?

时间:2010-04-25 22:26:51

标签: c++ stl vector sorting set

通常,使用排序std::vector而不是std::set会更有效。有没有人知道库类sorted_vector,它基本上具有与std::set类似的接口,但是将元素插入到排序的向量中(因此没有重复),使用二进制搜索到find元素等?

我知道写作并不难,但最好不要浪费时间并使用现有的实现。

更新:使用排序向量而不是集合的原因是:如果您有成千上万的小集合,每个集合只包含10个左右的成员,那么它的内存效率更高只需使用有序矢量。

6 个答案:

答案 0 :(得分:28)

Boost.Container flat_set

  

Boost.Container flat_ [multi] map / set容器是基于Austern和Alexandrescu指南的基于有序矢量的关联容器。这些有序的向量容器最近也受益于向C ++添加移动语义,大大加快了插入和擦除时间。扁平关联容器具有以下属性:

     
      
  • 比标准关联容器更快的查找
  •   
  • 比标准关联容器快得多的迭代次数。
  •   
  • 减少小对象(以及使用shrink_to_fit时的大对象)的内存消耗
  •   
  • 改进了缓存性能(数据存储在连续内存中)
  •   
  • 非稳定迭代器(插入和擦除元素时迭代器无效)
  •   
  • 无法存储不可复制和不可移动的值类型
  •   
  • 比标准关联容器更弱的异常安全性(复制/移动构造函数可以在删除和插入时移动值时抛出)
  •   
  • 比标准关联容器(特别是对于不可移动类型)更慢的插入和擦除
  •   

Live demo

#include <boost/container/flat_set.hpp>
#include <iostream>
#include <ostream>

using namespace std;

int main()
{
    boost::container::flat_set<int> s;
    s.insert(1);
    s.insert(2);
    s.insert(3);
    cout << (s.find(1)!=s.end()) << endl;
    cout << (s.find(4)!=s.end()) << endl;
}

  

jalf:如果你想要一个有序矢量,最好插入所有元素,然后在插入后调用std :: sort()一次。

boost::flat_set可以自动执行

template<typename InputIterator> 
flat_set(InputIterator first, InputIterator last, 
         const Compare & comp = Compare(), 
         const allocator_type & a = allocator_type());
  

效果:使用指定的比较对象和分配器构造一个空集,并插入范围[first,last)中的元素。

     

复杂度:如果范围[first,last]已经使用comp排序,则为N线性,否则为 N * log(N),其中N为last - first 。

答案 1 :(得分:7)

这样的容器不属于标准库的原因是它效率低下。使用向量进行存储意味着如果在向量的中间插入了某些内容,则必须移动对象。在每次插入时执行此操作会变得非常昂贵。 (平均而言,每次插入都需要移动一半的物体。这非常昂贵)

如果你想要一个有序矢量,最好插入所有元素,然后在插入后调用std::sort() 一次

答案 2 :(得分:5)

我认为STL中没有“已排序的容器”适配器,因为已经存在适当的关联容器,用于保存在几乎所有情况下都适合使用的事物。说实话,关于我能想到排序vector<>容器的唯一原因可能是与期望排序数组的C函数进行互操作。当然,我可能会遗漏一些东西。

如果您认为排序的vector<>更适合您的需求(意识到将元素插入向量中的缺点),这里是代码项目的实现:

我从来没有使用它,所以我不能保证(或许可证 - 如果有的话)。但是快速阅读一篇文章,看起来作者至少为容器适配器做了很好的努力,以便有一个合适的STL接口。

似乎值得仔细研究。

答案 3 :(得分:4)

如果你决定推出自己的,你可能还想看看boost:ublas。具体做法是:

#include <boost/numeric/ublas/vector_sparse.hpp>

并查看coordinate_vector,它实现了值和索引的向量。此数据结构支持O(1)插入(违反排序),但随后对按需Omega(n log n)进行排序。当然,一旦它被排序,查找就是O(logn)。如果对数组的一部分进行排序,则算法会识别此并仅对新添加的元素进行排序,然后进行就地合并。如果你关心效率,这可能是你能做到的最好的。

答案 4 :(得分:3)

Alexandresu的Loki有一个排序的矢量实现,如果你不想通过相关的无意义的努力滚动你自己。

http://loki-lib.sourceforge.net/html/a00025.html

答案 5 :(得分:0)

Here是我已经在生产代码中使用多年的sorted_vector类。它有重载让您使用自定义谓词。我已将它用于指针容器,这在很多用例中都是一个非常好的解决方案。