假设我有一个大小为n的std::vector(让我们称之为myVec),构造一个由元素X到Y的副本组成的新向量,其中0 <= X <= Y <= N-1,最简单的方法是什么?例如,大小为150000的向量中的myVec[100000]到myVec[100999]。

如果这不能有效地用一个向量,是否有另一种STL数据类型,我应该使用代替?


当前回答

你可以使用insert

vector<type> myVec { n_elements };

vector<type> newVec;

newVec.insert(newVec.begin(), myVec.begin() + X, myVec.begin() + Y);

其他回答

投射一个不是线性时间的集合的唯一方法是惰性地这样做,其中产生的“vector”实际上是委托给原始集合的子类型。例如,Scala的List#subseq方法在常数时间内创建一个子序列。但是,只有当收集是不可变的并且底层语言支持垃圾收集时,这才有效。

vector<T>::const_iterator first = myVec.begin() + 100000;
vector<T>::const_iterator last = myVec.begin() + 101000;
vector<T> newVec(first, last);

这是一个O(N)运算来构造新的向量,但是没有更好的方法了。

我打赌第一个编码器现在已经完成了。 对于简单的数据类型,不需要复制,只需恢复到良好的旧C代码方法。

std::vector <int>   myVec;
int *p;
// Add some data here and set start, then
p=myVec.data()+start;

然后将指针p和len传递给任何需要子向量的对象。

Notelen一定是!!len < myVec.size()-start

还有另一个选择: 例如,当在thrust::device_vector和thrust::host_vector之间移动时很有用,在那里您不能使用构造函数。

std::vector<T> newVector;
newVector.reserve(1000);
std::copy_n(&vec[100000], 1000, std::back_inserter(newVector));

复杂度也应该是O(N)

您可以将此与顶部答案代码结合起来

vector<T>::const_iterator first = myVec.begin() + 100000;
vector<T>::const_iterator last = myVec.begin() + 101000;
std::copy(first, last, std::back_inserter(newVector));

也许GSL库中的array_view/span是一个不错的选择。

这里还有一个单独的文件实现:array_view。