假设我有一个大小为n的std::vector(让我们称之为myVec),构造一个由元素X到Y的副本组成的新向量,其中0 <= X <= Y <= N-1,最简单的方法是什么?例如,大小为150000的向量中的myVec[100000]到myVec[100999]。
如果这不能有效地用一个向量,是否有另一种STL数据类型,我应该使用代替?
假设我有一个大小为n的std::vector(让我们称之为myVec),构造一个由元素X到Y的副本组成的新向量,其中0 <= X <= Y <= N-1,最简单的方法是什么?例如,大小为150000的向量中的myVec[100000]到myVec[100999]。
如果这不能有效地用一个向量,是否有另一种STL数据类型,我应该使用代替?
当前回答
假设有两个向量。
vector<int> vect1{1, 2, 3, 4};
vector<int> vect2;
方法1。使用拷贝功能。copy(first_iterator_index, last_iterator_index, back_inserter()):-该函数有3个参数,首先,旧vector的第一个迭代器。其次,old vector的最后一个迭代器和第三个迭代器是back_inserter函数,用于从back插入值。
// Copying vector by copy function
copy(vect1.begin(), vect1.end(), back_inserter(vect2));
方法2。通过使用赋值函数。分配(first_iterator_o last_iterator_o)。该方法将相同的值赋给新向量和旧向量。它有两个参数,第一个迭代器指向旧向量,最后一个迭代器指向旧向量。
//Copying vector by assign function
vect2.assign(vect1.begin(), vect1.end());
其他回答
这个讨论已经很老了,但是最简单的一个还没有提到,就是列表初始化:
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;
你可以使用insert
vector<type> myVec { n_elements };
vector<type> newVec;
newVec.insert(newVec.begin(), myVec.begin() + X, myVec.begin() + Y);
现在,我们使用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.
也许GSL库中的array_view/span是一个不错的选择。
这里还有一个单独的文件实现:array_view。
当M是子向量的大小时,可以使用性能为O(M)的STL复制。