是否可以在 C++ 中更改向量的开始位置以清除其前 n 个元素?

Posted

技术标签:

【中文标题】是否可以在 C++ 中更改向量的开始位置以清除其前 n 个元素?【英文标题】:Is it possible to change the begin position of a vector in C++ to clear its first n elements? 【发布时间】:2020-04-09 07:22:09 【问题描述】:

假设我有一个整数向量 [1,2,3,4,5,6,7]。据我所知,向量有一个内存地址@v,然后如果我们想访问一个元素i,我们只需要做@v+i*size_of_element。也许我错了,std::vector 的实现方式不同。

如果我想删除前 4 个元素并以 [5,6,7] 结尾,我是否只需要更新 @v 并清除元素,在这种情况下它们只是整数,所以我' m 假设它是 O(1)。

我的假设是否错误,有什么方法可以在 C++ 中使用向量实现这一点,即更新向量的起始地址以“清除”前 n 个元素?

如果没有,是否可以使用 std::list?

【问题讨论】:

C 中没有向量,并且您的标题明确提到了 C++。两者都是非常不同的语言。请不要添加无关的标签。 “也许我错了,std::vector 是用不同的方式实现的”不管vector是如何实现的,你都不应该乱搞实现细节,而应该使用它的公共API,你浏览过some reference 看看它提供了哪些方法? 您在抽象地谈论@v。如果你展示真实的代码,事情会清楚得多。这也将阐明“更新@v”的含义。有std::vector::erase(),但不会更新std::vector::data() 【参考方案1】:

这在理论上是可能的,其他一些语言在数组上也有类似的操作(我想到了 Go 和 Rust 中的 slices)。但是,std::vector 本身并不提供这样的功能。

无论是哪种语言,您“删除”的元素都不会真正从内存中消失,因为内存仍在分配中;充其量,您可以在底层数组上获得一个“视图”,它在开始或结束时省略了许多元素。

获得这种“视图”的 C++ 方法是使用一对迭代器。例如,my_vector.begin() + 4my_vector.end() 表示除前 4 个之外的所有元素(假设至少有 4 个)。所有在范围上运行的std 算法都接受迭代器对,这使得它成为一种有用的表示。

std::list 确实允许你从前面真正删除一些元素,但是操作是 O(n) 其中 n 是删除元素的数量.这是因为每个元素都需要单独遍历和释放。

【讨论】:

【参考方案2】:

不,你不能。您可以像这样轻松地从第一个向量构造另一个向量:

vector<int> newOne(old.begin()+4,old.end());

【讨论】:

这个操作会复制另一个向量,对吧? 是的,但是根据向量的内容,它可能不会那么昂贵......这就是您可以可靠地做的所有事情。访问data 可能会做一些棘手的事情,但这将是棘手

以上是关于是否可以在 C++ 中更改向量的开始位置以清除其前 n 个元素?的主要内容,如果未能解决你的问题,请参考以下文章

获取向量中字符的位置(C++)

在定义的位置初始化向量向量 - C++

如何清除向量中的所有元素,除了C++中向量中的最后一个元素

在 C++ 和 C# 之间传递向量结构

通过 C++ 中的外部函数更改存储在另一个对象的向量中的对象中元素的值

通过引用传递向量然后调用清除