8

私はJavaからC++を使用していますが、std :: vectorから削除したい要素(非プリミティブ)があるという一般的な設計状況があります。

Javaでは、次のように記述します。arrayList.remove(arrayList.indexOf(myClassInstance));

C ++では、std :: vectorを使用して、これを行うための最良/最もパフォーマンスの高い/最もクリーンな方法は何ですか?

私が考えることができる最善のことは、検索しているインスタンスへの参照を作成し、その参照が見つかるまでベクトルを反復処理することです。基本的に、一致するまで、ベクトル内の各要素のメモリアドレスを参照と比較します。

私は正しい方向に進んでいますか?またはこれを行うためのより良い方法はありますか?(おそらく別のstdコンテナを使用しており、これまではstd :: vectorのみを使用していました。)

4

3 に答える 3

8
#include <algorithm>

std::vector<Foo>::iterator it = std::find(vec.begin(), vec.end(), foo_2b_found);
if (it != vec.end()) vec.erase(it);
于 2010-11-22T00:12:06.477 に答える
4

std::find要素を検索しvector::eraseて削除するために使用します。

std::find基本的に、ベクトルを反復処理して要素を見つけます。単純なベクトルでは、これ以上のことはできません(Javaの場合も同じですArrayList)。別のコンテナを使用する必要があるかどうかは、要件によって異なります。

于 2010-11-22T00:08:32.373 に答える
1

ベクトルを直線的に検索したい場合は、

seq.erase( std::find( seq.begin(), seq.end(), elt ));

述語があり、述語に一致するすべてのアイテムを削除したい場合は、次のようにします。

seq.erase( std::remove_if( seq.begin(), seq.end(), Pred ), seq.end());

これらの方法はいずれも線形ルックアップを必要とするため、最もパフォーマンスの高い方法ではありません。また、要素が早い段階で見つかった場合でも、他のすべての要素を一定の位置で移動して連続させる必要があるため、消去にはコストがかかります。

std :: listを使用すると、これらの後者に対処できます。検索は線形になりますが、消去は一定時間になります。

キールックアップを使用する連想コンテナに要素を格納できる場合は、より効率的です。O(log N)ルックアップと定数時間の削除です。

ハッシュマップはさらに優れている可能性があり、一定時間のルックアップと削除に近い場合があります。

提案していること、つまりオブジェクトのポインターによる消去には、タイプTにstd :: setを使用できます。次にmySet.erase( pt );、ptがポインターである場所を使用します。もちろん、ポインターの存続期間を管理する必要がありますが、コレクションからどのポインターを消去するかがわかっているという事実は、他の場所にポインターのコピーがあることを示唆しています。

std :: set、SharedPtrLess>を使用できます

ここで、SharedPtrLessを次のように定義します。

template< typename T >
struct SharedPtrLess
{
   bool operator()( boost::shared_ptr<T> left, boost::shared_ptr<T> right ) const
   {
     return std::less<T>()( left.get(), right.get());
   }
};
于 2010-11-22T00:21:53.627 に答える