从vector中提取子vector的最佳方法是什么?
假设我有一个大小为N
的std::vector
(我们称之为myVec
)。 构造由元素X到Y的副本组成的新向量的最简单方法是什么?其中0 <= X <= Y <= N-1? 例如, myVec [100000]
通过myVec [100999]
中的一个大小为150000
的向量。
如果这不能有效地完成一个向量,是否有另一个我应该使用的STL数据types呢?
vector<T>::const_iterator first = myVec.begin() + 100000; vector<T>::const_iterator last = myVec.begin() + 101000; vector<T> newVec(first, last);
这是一个O(N)操作来构造新的vector,但没有一个更好的方法。
只需使用vector构造函数。
std::vector<int> data(); // Load Z elements into data so that Z > Y > X std::vector<int> sub(&data[100000],&data[101000]);
std::vector(input_iterator, input_iterator)
,你的情况foo = std::vector(myVec.begin () + 100000, myVec.begin () + 150000);
,例如在这里看到
如果两者都不会被修改(没有添加/删除项目 – 只要您注意线程问题,修改现有的项目就没有问题),您可以简单地通过data.begin() + 100000
和data.begin() + 101000
,假装它们是一个更小的向量的begin()
和end()
。
或者,由于vector存储保证是连续的,所以可以简单地传递一个1000个数组的数组:
T *arrayOfT = &data[0] + 100000; size_t arrayOfTLength = 1000;
这两种技术都需要一定的时间,但是要求数据长度不会增加,从而触发重新分配。
你没有提到什么types的std::vector<...> myVec
是,但如果它是一个简单的types或结构/类不包括指针,并且你想要最好的效率,那么你可以做一个直接的内存复制(我认为这将比其他答案更快)。 这里是std::vector<type> myVec
一个通用示例,其中type
为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
当M是子向量的大小时,可以使用带有O(M)性能的STL副本 。
投射不是线性时间的集合的唯一方法就是懒洋洋地这样做,结果的“vector”实际上是委托给原始集合的子types。 例如,Scala的List#subseq
方法在常量中创build一个子序列。 但是,这只有在集合是不可变的,并且基础语言运动垃圾收集时才有效。
好。 这是一个很老的讨论。 但是我发现了一些简洁的东西:
slice_array – 这可能是一个快速的select? 我没有testing过。
也许在GSL库中的array_view / span是个不错的select。
这里也是一个单独的文件实现: array_view 。
目前,我们有Guideline Support Library的span<T>
结构,请参阅:
指南支持库检查:范围 P0122:范围:对象序列的边界安全视图
你会这样做:
#include <gsl/span> ... auto my_subspan = gsl::as_span(myvec).subspan(100000, 1000);
获得1000个与myvec
相同types的元素。 现在,这不是一个副本,它只是向量中的数据视图 ,所以要小心。 如果你想要一个实际的副本,你可以这样做:
std::vector<T> new_vec(my_subspan.begin(), my_subspan.end());
张贴这个迟到只为其他人..我敢打赌,第一个编码器是现在完成。 对于简单的数据types,不需要拷贝,只需要恢复到旧的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