如何有效地从C ++中的集合中删除开始和结束元素?

时间:2018-04-13 18:15:02

标签: c++ stl

如果我设置如下:

set<int> dummyset = {2,3,4,5,6,7,8};

auto itr = dummyset.find(5);

如果我想从2 to 4删除,我会输入dummyset.erase(dummyset.begin(), itr);

但这需要线性时间。

假设我打算总是想从两端删除两个块,我可以只移动开始指针或结束指针(常量时间)而不是删除每个元素(线性时间)吗?

示例:

begin     end
|           |
V           V
1  2  3  4  5

// Delete {1,2} and {5} by moving pointers

1  2  3  4  5
      ^  ^
      |  |
  begin  end

感谢。

3 个答案:

答案 0 :(得分:7)

你不能,也可能不需要。

C ++的算法采用迭代器对。因此,而不是dummyset.begin()dummyset.end(),将调整后的迭代器传递给它们。

但是,如果您使用的是set成员函数(例如成员.find()),则无法绕过它 - 您需要实际擦除。没有办法告诉这些函数暂时作用于子范围而不是整个容器(我认为这是你要求的)。

可能性并不像你想象的那么糟糕。实现知道它正在做什么,并且应该仅在实际需要的情况下重新平衡其内部树,给定要删除的元素的范围

答案 1 :(得分:0)

  

我怎样才能跳过实际擦除并重置开始指针或结束指向itr的指针,这可以在恒定时间内完成?

对于可移植代码,您需要创建一个公开此功能的其他容器。

std::set故意限制对其底层指针的访问,因为在the established interface之外操纵它们会很容易引入对象泄漏,内存泄漏以及std::set用户受到保护的未定义行为。

答案 2 :(得分:0)

通常将std算法定义为对成对的开始/结束迭代器进行操作。因此,您可能希望使用按需创建的一对迭代器[in / de]来实现视图。