web-dev-qa-db-ja.com

前面のベクターへの挿入

iterator insert ( iterator position, const T& x );

std::Vectorクラスの挿入演算子の関数宣言です。

この関数の戻り値の型は、挿入された要素を指す反復子です。私の質問は、この戻り型を考えると、最も効率的な方法は何ですか(これは速度が重要な場所で実行している大きなプログラムの一部であるため、most計算効率の良い方法を探しています)初めに挿入します。以下ですか?

//Code 1
vector<int> intvector;
vector<int>::iterator it;
it = myvector.begin();
for(int i = 1; i <= 100000; i++){
    it = intvector.insert(it,i);
}

または、

//Code 2
vector<int> intvector;
for(int i = 1; i <= 100000; i++){
    intvector.insert(intvector.begin(),i);
}

基本的に、コード2のパラメーターは、

intvector.begin() 

コード1で返されたイテレータを使用する場合と比較して、計算的に評価するための「コスト」、または両方とも同等に安価/コストが高い必要がありますか?

42
Tryer

挿入ポイントを取得する効率は、少なくとも重要ではありません-挿入を行うたびに既存のデータを絶えずシャッフルすることの非効率によってd化されます。

これにはstd :: dequeを使用してください。それが設計された目的です。

41
Mark Ransom

プログラムの重要なニーズの1つがコンテナの先頭に要素を挿入する:である場合、std::dequeではなくstd::vectorを使用する必要があります。 std::vectorは、最後に要素を挿入する場合にのみ有効です。

STL diagram for choosing containers

他のコンテナはC++ 11で導入されました。これらの新しいコンテナで更新されたグラフを見つけて、ここに挿入する必要があります。

114

古いスレッドですが、Googleクエリの最初の検索結果として同僚のデスクに現れました。

検討する価値のあるdequeを使用する代わりの方法が1つあります。

std::vector<T> foo;
for (int i = 0; i < 100000; ++i)
  foo.Push_back(T());
std::reverse( foo.begin(), foo.end() );

パフォーマンスのためにdequeよりも大幅に設計されたベクターを引き続き使用します。また、スワップ(逆に使用するもの)は非常に効率的です。一方、複雑さは依然として線形ですが、50%増加しています。

いつものように、何をすべきかを決める前に測定してください。

28

ほとんどの場合、dequeが他の人が提案する適切なソリューションです。ただし、完全を期すために、このフロント挿入を1回だけ行う必要があり、プログラムの他の場所ではフロントで他の操作を行う必要がなく、そうでなければvectorが必要なインターフェースを提供すると仮定します。これらすべてが当てはまる場合、非常に効率的なPush_back次にreverseは、すべてを順番に取得するためのベクトルです。これは、前に挿入するときのような多項式ではなく線形の複雑さを持ちます。

12
Mark B

前方に挿入する計算効率の良い方法を探しているなら、おそらくベクターの代わりにdequeを使いたいでしょう。

12
Tim Rupe

最初にデータを挿入したい場合は、コンテナのタイプを変更する必要があると思います。これが、ベクターにPush_front()メンバー関数がない理由です。

2
Hongseok Yoon

ベクトルを使用すると、通常、実際に持つ要素の数がわかります。この場合、必要な数の要素(表示する場合は100000)を予約し、[]演算子が最速の方法です。本当に効率的な挿入が必要な場合は、アルゴリズムに応じてdequeまたはlistを使用できます。

また、アルゴリズムのロジックを反転し、最後に挿入することを検討することもできます。これは通常、ベクトルの場合は高速です。

2
Diego Sevilla

直感的には、@ Happy Green Kid Napsに同意し、小さなサイズ(プリミティブデータ型の1 << 10要素)では問題にならないことを示す小さなテストを実行しました。ただし、コンテナサイズが大きい場合(1 << 20)、std::dequeは、std::vector。したがって、決定する前にベンチマークを行います。別の要因は、コンテナの要素タイプです。

  • テスト1:Push_front(a)1 << 10または(b)1 << 20 uint64_t into std :: deque
  • テスト2:Push_back(a)1 << 10または(b)1 << 20 uint64_t into std :: vector続いてstd :: reverse

結果:

  • テスト1-deque(a)19 µs
  • テスト2-ベクトル(a)19 µs
  • テスト1-deque(b)6339 µs
  • テスト2-ベクトル(b)10588 µs
0
Marie Hoffmann