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

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


当前回答

只要使用向量构造函数。

std::vector<int>   data();
// Load Z elements into data so that Z > Y > X

std::vector<int>   sub(&data[100000],&data[101000]);

其他回答

还有另一个选择: 例如,当在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。

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

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

如果这两个都不打算修改(不添加/删除项-只要注意线程问题,修改现有项就可以),您可以简单地传递data.begin() + 100000和data.begin() + 101000,并假装它们是一个更小的向量的begin()和end()。

或者,因为矢量存储保证是连续的,你可以简单地传递一个1000项数组:

T *arrayOfT = &data[0] + 100000;
size_t arrayOfTLength = 1000;

这两种技术都需要固定的时间,但要求数据长度不增加,从而触发重新分配。

这个讨论已经很老了,但是最简单的一个还没有提到,就是列表初始化:

 vector<int> subvector = {big_vector.begin() + 3, big_vector.end() - 2}; 

它要求c++11或以上。

使用示例:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main(){

    vector<int> big_vector = {5,12,4,6,7,8,9,9,31,1,1,5,76,78,8};
    vector<int> subvector = {big_vector.begin() + 3, big_vector.end() - 2};

    cout << "Big vector: ";
    for_each(big_vector.begin(), big_vector.end(),[](int number){cout << number << ";";});
    cout << endl << "Subvector: ";
    for_each(subvector.begin(), subvector.end(),[](int number){cout << number << ";";});
    cout << endl;
}

结果:

Big vector: 5;12;4;6;7;8;9;9;31;1;1;5;76;78;8;
Subvector: 6;7;8;9;9;31;1;1;5;76;