Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是否有支持insert()等的排序向量类。?_C++_Stl_Vector_Sorting_Set - Fatal编程技术网

C++ 是否有支持insert()等的排序向量类。?

C++ 是否有支持insert()等的排序向量类。?,c++,stl,vector,sorting,set,C++,Stl,Vector,Sorting,Set,通常,使用排序的std::vector比使用std::set更有效。有人知道一个库类sorted_vector,它基本上与std::set有一个类似的接口,但是它将元素插入到排序的向量中(这样就不会有重复项),使用二进制搜索来查找元素,等等 我知道写起来并不难,但最好还是不要浪费时间使用现有的实现 更新:使用排序向量而不是集合的原因是:如果有成千上万个小集合,每个集合只包含10个左右的成员,只使用排序向量更节省内存。我认为STL中没有“排序容器”适配器,因为已经有了适当的关联容器来保持事物的排序

通常,使用排序的
std::vector
比使用
std::set
更有效。有人知道一个库类
sorted_vector
,它基本上与
std::set
有一个类似的接口,但是它将元素插入到排序的向量中(这样就不会有重复项),使用二进制搜索来
查找
元素,等等

我知道写起来并不难,但最好还是不要浪费时间使用现有的实现


更新:使用排序向量而不是集合的原因是:如果有成千上万个小集合,每个集合只包含10个左右的成员,只使用排序向量更节省内存。

我认为STL中没有“排序容器”适配器,因为已经有了适当的关联容器来保持事物的排序,这几乎适用于所有情况。老实说,对于使用排序的
vector
容器,我能想到的唯一原因可能是与期望排序数组的C函数进行互操作。当然,我可能遗漏了什么

如果您觉得排序后的
向量
更适合您的需要(注意在向量中插入元素的缺点),下面是代码项目的一个实现:

我从未使用过它,所以我不能担保它(或者它的许可证——如果有指定的话)。但是快速阅读这篇文章,看起来作者至少为容器适配器提供了一个合适的STL接口做出了很大的努力


它似乎值得仔细研究。

这样一个容器不是标准库的一部分的原因是它效率低下。使用向量来存储,如果对象插入到向量的中间,对象必须被移动。在每次插入时都这样做会花费不必要的成本。(平均而言,每次插入都要移动一半的对象。这相当昂贵)


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

Alexandresu的Loki有一个排序向量实现,如果您不想经历自己的滚动过程


如果您决定推出自己的,您可能还想看看boost:ublas。具体而言:

#include <boost/numeric/ublas/vector_sparse.hpp>
#包括
看看坐标向量,它实现了一个值和索引向量。此数据结构支持O(1)插入(违反排序),但随后按需对Omega(n log n)进行排序。当然,一旦对其进行了排序,查找将是O(logn)。如果对数组的一部分进行了排序,则算法会识别出这一点,并仅对新添加的元素进行排序,然后执行就地合并。如果你关心效率,这可能是你能做的最好的了。

容器平面[multi]map/set容器是基于奥斯特和亚历山德雷斯库指南的有序向量关联容器。这些有序的向量容器最近也受益于向C++添加移动语义,从而大大加快了插入和删除时间。平面关联容器具有以下属性:

  • 比标准关联容器更快的查找速度
  • 比标准关联容器更快的迭代
  • 小对象的内存消耗更少(如果使用了“收缩到”匹配,则大对象的内存消耗更少)
  • 提高缓存性能(数据存储在连续内存中)
  • 非稳定迭代器(插入和删除元素时迭代器无效)
  • 无法存储不可复制和不可移动的值类型
  • 与标准关联容器相比,异常安全性较弱(在擦除和插入中移动值时,复制/移动构造函数可能抛出)
  • 插入和擦除速度比标准关联容器慢(特别是不可移动的类型)
:

#包括
#包括
#包括
使用名称空间std;
int main()
{
boost::container::flat_set s;
s、 插入(1);
s、 插入(2);
s、 插入(3);

cout是我的排序向量类,多年来我一直在生产代码中使用它。它有重载,可以让您使用自定义谓词。我将它用于指针容器,这在许多用例中都是一个非常好的解决方案。

我认为没有现成的类用于此。您可以编写自己的或使用
下限()
用于插入和
二进制搜索()
用于查找。如果向量太小,二进制搜索和顺序搜索之间的差异可能也很小,因此您最好使用std::vector。由于集合将导致缓存未命中,差异可能会很大。@Frank:我回答这个问题有点晚,但无论如何:)您应该检查二进制搜索是否正确“10左右”排序向量中的拱元素的速度比线性搜索快。很可能不是更快,甚至可能更慢,因为处理器的分支预测将在这种情况下发挥重要作用。马特·奥斯特恩的相关论文:。我不知道这将如何解决问题。即使只是指针交换,所有对象仍必须被触摸。你仍然在试图做一些数据结构不适合的事情。我开始写这样一个答案,然后停下来,因为它根本不是真的。对于不到几十个元素,这是非常普遍的,平均移动一半可以很容易地比执行分配和树重新平衡更便宜。当然se最好调用
sort
一次,我个人不会找一个容器来做这件事,但这是一个风格问题。在排序数组中插入n个元素是logn来查找插入点,n/2来查找mov
#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;
}
template<typename InputIterator> 
flat_set(InputIterator first, InputIterator last, 
         const Compare & comp = Compare(), 
         const allocator_type & a = allocator_type());