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

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


当前回答

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

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

其他回答

只要使用向量构造函数。

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

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

std::vector<T>(input_iterator, input_iterator),在你的情况下,foo = std::vector<T>(myVec。begin () + 100000, myVec。Begin() + 150000);,参见这里的示例

你没有提到什么类型std::vector<…> myVec是,但如果它是一个简单的类型或结构/类,不包括指针,你想要最好的效率,那么你可以做一个直接的内存复制(我认为这将比其他答案提供的更快)。下面是std::vector<type> myVec的一般示例,这里的类型是int:

typedef int type; //choose your custom type/struct/class
int iFirst = 100000; //first index to copy
int iLast = 101000; //last index + 1
int iLen = iLast - iFirst;
std::vector<type> newVec;
newVec.resize(iLen); //pre-allocate the space needed to write the data directly
memcpy(&newVec[0], &myVec[iFirst], iLen*sizeof(type)); //write directly to destination buffer from source buffer

现在,我们使用span !所以你可以这样写:

#include <gsl/span>

...
auto start_pos = 100000;
auto length = 1000;
auto span_of_myvec = gsl::make_span(myvec);
auto my_subspan = span_of_myvec.subspan(start_pos, length);

以获得与myvec相同类型的1000个元素的跨度。或者更简洁的形式:

auto my_subspan = gsl::make_span(myvec).subspan(1000000, 1000);

(但我不太喜欢这个,因为每个数字参数的含义并不完全清楚;如果长度和start_pos是同一个数量级,情况会变得更糟。)

不管怎样,记住这不是一个副本,它只是向量中数据的一个视图,所以要小心。如果你想要一个实际的副本,你可以这样做:

std::vector<T> new_vec(my_subspan.cbegin(), my_subspan.cend());

注:

gsl stands for Guidelines Support Library. For more information about gsl, see: http://www.modernescpp.com/index.php/c-core-guideline-the-guidelines-support-library. There are several gsl implementations . For example: https://github.com/martinmoene/gsl-lite C++20 provides an implementation of span. You would use std::span and #include <span> rather than #include <gsl/span>. For more information about spans, see: What is a "span" and when should I use one? std::vector has a gazillion constructors, it's super-easy to fall into one you didn't intend to use, so be careful.

Vector::assign可能是另一个解决方案

// note: size1 < src.size() && size2 < src.size()
std::vector<int> sub1(size1), sub2(size2);
sub1.assign(src.begin(), src.begin() + size1);
sub2.assign(src.begin(), src.begin() + size2);