2

私は以前にこの質問をしました。std :: setに興味がありますが、別の紛らわしいシナリオがあります。

つまり、次のコードは、T = std::vectorおよびT=std::setの合法でポータブルなc++です。

template <typename T>
void remove_elements(T& collection, int removal_value)
{
    typename T::iterator new_end = 
        std::remove(collection.begin(), collection.end(), removal_value);
    collection.erase(new_end, collection.end());
}

SGIリファレンスによると、set::iteratorとset::const_iteratorは同じであるため、これが正当であるかどうかはわかりません。しかし、タイプに関係なく、必要な操作を実行する別の方法を見つけることができないようです。テンプレートの特殊化に頼ることもできますが、そもそも特殊化する必要がないのはいいことです。

4

3 に答える 3

2

erase-remove イディオムは、シーケンス コンテナーに対してのみ機能します。標準の連想コンテナでは機能せず、ソリューションはそれほど単純ではありません。

2 つのアプローチ:

  1. remove_copy_ifすべての値を別の一時コンテナーにコピーしてから、元のコンテナーの内容を一時コンテナーの内容と交換するために使用します。[関連する Q への私の回答を参照してください]
  2. もう 1 つは、コンテナー要素をウォークするループであり、イテレーターを渡して消去するときにイテレーターをポスト インクリメントします。

詳細については、この Q を参照してください: std::map と同等の remove_if

また、アイテム 9 も参照してください。Scott Meyers による効果的な STL の消去オプションから慎重に選択してください。

于 2009-05-27T06:43:40.030 に答える
1

いいえ、 では機能しません。std::setの要件の 1 つはstd::remove()、イテレータが可変イテレータであり、std::setのイテレータが可変でないためです。

残念ながら、提案する良い代替手段はありません。できることの 1 つはstd::find()、 を使用して要素の出現に対するイテレータを見つけ、.erase()イテレータ ( と の両方std::vectorに存在するstd::set) でメソッドを使用してそれを消去することです。そのような要素がなくなるまでそれを続けます。しかし、これは非常に非効率的で、O(n) ではなく O(n^2) になる可能性があります。

于 2009-05-27T06:32:42.093 に答える
0

「正しい」答えは、のためにオーバーロードすることだと思いremove_elementsますstd::set。セットは順序付けられており、重複が含まれていないため、removal_valueに等しい要素の削除は、ベクトルまたは汎用シーケンスの場合よりもはるかに簡単です。次のことができたとしても、すべてに同じアルゴリズムを使用する必要はありません。

template <typename T>
void remove_elements(T& collection, const typename T::value_type& removal_value)
{
    typename T::iterator new_end = 
        std::remove(collection.begin(), collection.end(), removal_value);
    collection.erase(new_end, collection.end());
}

template<typename T>
void remove_elements(std::set<T>& collection, const T& removal_value)
{
    collection.erase(removal_value);
}

これらがあいまいであるかどうかについて少し心配していますが、最も明白なユースケースでは、これらは私にとっては問題なく機能しているようです。

std :: set以外の一意のソート済み連想コンテナがある場合、これは少し面倒です。std :: swapテリトリーに移動します。ここでは、実装するすべてのクラスがremove_elementsのオーバーロードを提供する必要があります。しかし、セットはあなたが質問している唯一のクラスなので、少なくとも今のところ、それがあなたが実際に使用している唯一のトリッキーなケースだと思います。必要に応じて、トレイトを使用して、コンテナのプロパティに基づいてアルゴリズムの適切なバージョンを選択できます。

于 2009-05-27T11:58:21.773 に答える