サイズがmyVec
のstd::vector
(N
と呼びましょう)があるとします。 XからYまでの要素のコピーからなる新しいベクトルを作る最も簡単な方法は何ですか?0 <= X <= Y <= N-1?たとえば、サイズがmyVec [100000]
のベクトルのmyVec [100999]
から150000
まで。
ベクトルでこれを効率的に行うことができない場合は、代わりに使用すべき別の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(input_iterator, input_iterator)
、あなたの場合はfoo = std::vector(myVec.begin () + 100000, myVec.begin () + 150000);
、例えば参照してください ここ
最近はspan
sを使っています。だからあなたは書くだろう:
#include <gsl/span>
...
auto start_pos = 100000;
auto length = 1000;
auto my_subspan = gsl::make_span(myvec).subspan(start_pos, length);
myvec
と同じ型の1000個の要素からなるスパンを取得します。さて、これはコピーではなく、ベクトル内のデータの単なる表示なので、注意してください。実際のコピーが必要な場合は、次のようにします。
std::vector<T> new_vec(my_subspan.cbegin(), my_subspan.cend());
ノート:
gsl
は、Guidelines Support Libraryの略です。 gsl
の詳細については、 http://www.modernescpp.com/index.php/c-core-guideline-the-guidelines-support-library を参照してください。gsl
の1つの実装については、 https://github.com/Microsoft/GSL を参照してください。span
の実装を提供します。 std::span
ではなく#include <span>
と#include <gsl/span>
を使用します。std::vector
には、数え切れないほどのコンストラクタがあります。使用するつもりがないものに陥るのは非常に簡単なので、注意してください。両方とも修正されないのであれば(スレッドの問題に注意している限り、既存のものを修正することはできません)、単にdata.begin() + 100000
とdata.begin() + 101000
を迂回して、それらがbegin()
とend()
のふりをすることができます。小さいベクトル.
あるいは、ベクトルストレージは連続していることが保証されているので、1000項目の配列を単純に渡すことができます。
T *arrayOfT = &data[0] + 100000;
size_t arrayOfTLength = 1000;
これらの手法はどちらも一定の時間がかかりますが、データの長さが増えずに再割り当てが行われることを必要とします。
std::vector<...> myVec
の型については触れていませんが、ポインタを含まない単純型または構造体/クラスで、最も効率的なものが必要な場合は、直接メモリコピーを実行できます(これより速いでしょう)。提供された他の答え)。これは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) performanceで STL copy を使用できます。
OK。これはかなり古い議論です。しかし、私はちょうど良いものを見つけました
slice_array - これは速い方法でしょうか。私はそれをテストしていません。
線形時間ではないコレクションを射影する唯一の方法は、結果として得られる「ベクトル」が実際には元のコレクションに委譲されているサブタイプであるため、遅延して実行することです。たとえば、ScalaのList#subseq
メソッドは一定時間でサブシーケンスを作成します。ただし、これはコレクションが不変であり、基になる言語がガベージコレクションを使用している場合にのみ機能します。
さらに別のオプション: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 。
insert
を使うことができます
vector<type> myVec { n_elements };
vector<type> newVec;
newVec.insert(newVec.begin(), myVec.begin() + X, myVec.begin() + Y);
あるベクトルから別のベクトルに要素を簡単にコピーする
この例では、わかりやすくするためにペアのベクトルを使用しています
`
vector<pair<int, int> > v(n);
//we want half of elements in vector a and another half in vector b
vector<pair<lli, lli> > a(v.begin(),v.begin()+n/2);
vector<pair<lli, lli> > b(v.begin()+n/2, v.end());
//if v = [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
//then a = [(1, 2), (2, 3)]
//and b = [(3, 4), (4, 5), (5, 6)]
//if v = [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7)]
//then a = [(1, 2), (2, 3), (3, 4)]
//and b = [(4, 5), (5, 6), (6, 7)]
'
ご覧のように、あるベクトルから別のベクトルに要素を簡単にコピーできます。たとえば、インデックス10から16の要素をコピーする場合は、次のようにします。
vector<pair<int, int> > a(v.begin()+10, v.begin+16);
また、インデックス10から最後までの要素にする場合は、その場合
vector<pair<int, int> > a(v.begin()+10, v.end()-5);
これが助けになることを願い、最後のケースではv.end()-5 > v.begin()+10
を覚えていてください
他人のためだけにこれを遅く投稿する..私は最初のコーダーが今で終わったと思います。単純なデータ型の場合、コピーは不要です。古き良き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