2011-10-15 8 views
5

私はある場合には一方向に、ある場合には別の方法でそれらを並べ替える必要があるデータセットを持っています。たとえば、データセットが文字列セット{"abc"、 "dfg"、...}であるとします。時にはアルファベット順に並べ替える必要があり、時にはその長さを比較する必要があります。C++ std :: setのコンパレータを変更することはできますか?

最初はデータのコンテナとしてstd :: setを使用し、2つのコンパレータを実装しました。セットのコンパレータをオンザフライで変更できることを願って、データが巨大で、コピーするのは良い考えではありませんあるセットから別のセットへ。私はちょうど時々異なるコンパレータを使ってそれをソートしたい。これは可能なのでしょうか、それを行う正しい方法は何ですか?

答えて

6

構築時にコンパレータをstd::setに指定する必要があります。

解決策として、実際のコレクションを参照する代わりに、2つの「インデックス」セットを維持します。これにより、最大限の柔軟性が得られます。一緒にすべてを保つために、私はあなたが単一のクラスでそれを包むお勧め:

// to be compiled, debugged etc..., but ideal 
// to grab the idea 
// caveats: maintain the index objects whenever the collection 
// gets resized/reallocated etc... 
// so not to be written yourself, use an existing library :) 
template< typename T, typename comp1, typename comp2 > 
struct MultiIndex { 
    std::deque<T> collection; 
    std::set<T*, comp1> index1; 
    std::set<T*, comp2> index2; 

    void insert(const T& t){ 
     collection.push_back(t); 
     index1.insert(&collection.back()); 
     index2.insert(&collection.back()); 
    } 
}; 

Boostライブラリは、このようなクラスがあります:Multiindex

+0

ありがとうxtofl!まさに私が欲しいもの。 – blurrcat

2

セットは内部で常にソートされています(そうしないと、必要なパフォーマンスが得られません)ので、コンパレータは変更できません。私はここで最高の解決策は、同じデータを持つ2つのセットを維持することですが、異なるコンパレータを使用することです。私はクラス内の2つのセットをカプセル化し、データが両方のセットで同じであることを保証するために両方のセットに挿入作業のような機能を持たせます。

データを常に並べ替える必要がない場合は、必要なものを達成する別の方法は、単に例を使用することです。必要なときに必要な比較器でベクトルとソートを行います。

1

いいえ、オンザフライではありません。ツリーは、構築時に指定されたソート基準に基づいて作成されます。 1つのデータセットに複数のインデックスを作成することについては、複数のセットで実現できます。おそらくこれのために作成された何かを持っているboostのようなlibsがたくさんあります。