STL:从A到B的自然数集

时间:2010-07-19 17:15:27

标签: c++ stl performance

我想在一组中添加A到B的自然数。目前我正在插入A到B中的每个数字,在这样的集合中逐个插入

set<int> s;
for(int j=A; j<=B; j++)
    s.insert(j);

但需要O(n)时间(此处n = (B - A)+1)。 STL中是否有任何预先定义的方法在O(1)时间内完成?

由于

6 个答案:

答案 0 :(得分:3)

分配内存以保持n号始终至少为O(n)所以我认为你运气不好。

答案 1 :(得分:2)

没有。使用顺序值填充容器所需的最短时间是O(n)时间。

答案 2 :(得分:2)

从技术上讲,我认为这是O(n log n)因为set.insert函数是log n。我认为O(n)是您能做的最好的事情,但为此您需要使用未分类的容器,例如vectorlist

答案 3 :(得分:2)

使用STL设置容器,您将永远不会获得O(1)时间。您可以通过使用set(InputIterator f, InputIterator l, const key_compare& comp)构造函数并传入迭代超过给定整数范围的自定义迭代器来减少运行时间。这可能运行得更快(取决于stl实现,编译器等)的原因是你正在减少调用堆栈深度。在你的代码片段中,你从.insert()调用一直到实际插入,然后返回每个整数。使用备用构造函数,您的增量操作将向下移动到执行插入的框架中。如果编译器无法内联,则递增操作现在可能具有函数调用的可能开销。你应该在采用这种方法之前对此进行基准测试如果您的stl实现具有.insert()的浅调用堆栈,则可能会更慢。

一般来说,如果你需要一组连续的整数范围,你可以通过实现一个专门的集合类来看到大量的性能提升,这个集合类只能存储和比较每个集合的上限和下限。

答案 4 :(得分:0)

O(1)仅适用于默认构造函数 O(n)用于复制构造函数和使用迭代器排序的序列 O(log n!)用于使用迭代器插入未排序的序列。

答案 5 :(得分:0)

好吧,如果你想要开箱即用,你可以设计一个“懒惰加载”的数组,自定义此任务。基本上,在访问时,如果先前未设置该值,则将确定正确的值。

这将允许设置为O(1)(假设初始化“之前未设置”标志本身为O(1)),但不会加快整体操作 - 它只会将时间分散剩下的运行(总体上可能需要更长的时间)。