如果我设置如下:
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
感谢。
答案 0 :(得分:7)
你不能,也可能不需要。
C ++的算法采用迭代器对。因此,而不是dummyset.begin()
和dummyset.end()
,将调整后的迭代器传递给它们。
但是,如果您使用的是set
成员函数(例如成员.find()
),则无法绕过它 - 您需要实际擦除。没有办法告诉这些函数暂时作用于子范围而不是整个容器(我认为这是你要求的)。
可能性并不像你想象的那么糟糕。实现知道它正在做什么,并且应该仅在实际需要的情况下重新平衡其内部树,给定要删除的元素的范围。
答案 1 :(得分:0)
我怎样才能跳过实际擦除并重置开始指针或结束指向itr的指针,这可以在恒定时间内完成?
对于可移植代码,您需要创建一个公开此功能的其他容器。
std::set
故意限制对其底层指针的访问,因为在the established interface之外操纵它们会很容易引入对象泄漏,内存泄漏以及std::set
用户受到保护的未定义行为。
答案 2 :(得分:0)