【问题标题】:How to efficiently insert a range of consecutive integers into a std::set?如何有效地将一系列连续整数插入 std::set?
【发布时间】:2026-02-14 01:40:02
【问题描述】:

在 C++ 中,我有一个 std::set,我想插入一系列连续整数。我怎样才能有效地做到这一点,希望在 O(n) 时间内,其中 n 是范围的长度?

我想我会使用 std::insert 的 inputIterator 版本,但不清楚如何构建输入迭代器。

std::set<int> mySet;

// Insert [34 - 75):
mySet.insert(inputIteratorTo34, inputIteratorTo75);

我如何创建输入迭代器,这将是 O(n) 的范围大小吗?

【问题讨论】:

  • 如果这是问题的唯一部分,那么我建议实现一个链表...O(1) push,n pushes = O(n)

标签: c++ insert integer range stdset


【解决方案1】:

将已排序的元素插入集合的有效方法是提示库下一个元素的位置。为此,您想使用带有迭代器的 insert 版本:

std::set<int>::iterator it = mySet.end();
for (int x : input) {
   it = mySet.insert(it, x);
}

另一方面,您可能需要考虑其他容器。尽可能使用std::vector。如果与查找相比插入量很小,或者如果所有插入都是预先发生的,那么您可以构建一个向量,对其进行排序并使用lower_bound 进行查找。在这种情况下,由于输入已经排序,您可以跳过排序。

如果插入(或删除)发生在各处,您可能需要考虑使用std::unordered_set&lt;int&gt;,它具有平均O(1) 插入(每个元素)和查找成本。

对于跟踪集合中的小数字的特殊情况,所有这些数字都很小(34 到 75 是小数字),您还可以考虑使用位集甚至是 bool 的普通数组,其中您将元素设置为true 插入时。要么有O(n)插入(所有元素)和O(1)查找(每个查找),这比集合更好。

【讨论】:

  • 我以为我看到了一些关联容器的措辞,即如果数据已经排序,它将是线性的。但这可能在 set 构造函数中,而不是在 insert 中。
【解决方案2】:

一种提升方式可能是:

 std::set<int> numbers(
 boost::counting_iterator<int>(0),
 boost::counting_iterator<int>(10));

其他答案非常棒LINK,特别是@Mani 的答案

【讨论】:

    【解决方案3】:

    std::set 是一种二叉搜索树,这意味着平均插入成本为 O(lgn),

    c++98:如果插入N个元素,一般是Nlog(size+N),但是是线性的 如果元素已经按照相同的方式排序,则为 size+N 容器使用的排序标准。

    c++11:如果插入N个元素,Nlog(size+N)。实现可能 如果范围已经排序,则进行优化。

    我认为C++98实现会跟踪当前插入节点,检查下一个要插入的值是否大于当前值,在这种情况下不需要从根开始。

    在c++11中,这是一个可选的优化,所以你可以实现一个skiplist结构,并在你的实现中使用这个范围插入特征,或者你可以根据你的场景优化程序

    【讨论】:

      【解决方案4】:

      根据aksham提供的提示,我看到答案是:

      #include <boost/iterator/counting_iterator.hpp>
      
      std::set<int> mySet;
      
      // Insert [34 - 75):
      mySet.insert(boost::counting_iterator<int>(34),
                   boost::counting_iterator<int>(75));
      

      【讨论】:

        【解决方案5】:

        不清楚为什么你特别想使用迭代器插入来指定范围。

        但是,我相信您可以使用简单的 for 循环插入所需的 O(n) 复杂度。

        引用 cppreference 在 std::set 上的页面,复杂性是:

        如果插入了 N 个元素,则通常为 Nlog(size+N),但如果元素已经根据容器使用的相同排序标准排序,则为 size+N 线性。

        所以,使用 for 循环:

        std::set<int> mySet;
        for(int i = 34; i < 75; ++i) 
          mySet.insert(i);
        

        【讨论】: