2016-08-23 20 views
0

コンテナ内に一意のオブジェクトを格納する必要があります。オブジェクトはoperator==operator!=operator<でもoperator>)です。オペレータのない一意の値を格納するコンテナ<

std::setは使用できません。operator<が必要です。 ハッシュ関数が必要なので、私はstd::unordered_setを使用することはできません。私のオブジェクトタイプ(または私は怠け者)を考慮して書くことができないとしましょう。

私は本当にstd::vectorを使用し、(std::findを使用するoperator==を使用して)アイテムがコンテナに重複しないようにしていますか?

operator==を使ってユニークなアイテムを格納するために使用できるコンテナは本当にありませんか?

+2

'std :: unordered_set'は' operator <'を必要としません – Slava

+0

['std :: unordered_set'](http://en.cppreference.com/w/cpp/container/unordered_set)は比較演算子を必要としません。これは、「順序付けられていない」データ構造 – Nelfeal

+1

のポイントです。唯一のことは、一意のオブジェクトにハッシュ関数を提供することです。 –

答えて

4

実際には標準的なコンテナはありません。これは、非効率的なためです。 O(N)、正確には - まさにあなたが想像している強引な力の検索です。

両方std::set<T>std::unordered_set<T>コンテナの既存のNのメンバーのいずれかが潜在的な新しい値Vに等しいとすることができる、プロパティのいずれかを欠くTの非自明性を利用して力まかせ探索を回避し、そしてしたがって、N個のメンバーをすべてoperator==を繰り返し使用して比較する必要があります。あなたがstd::vector::push_backまたはstd::vector::insert要素がすでにベクター内に存在するかどうかを確認するために最初std::findを使用する前に

+0

標準が開発されないことを意味しますか、効率的ではないため「ユニークベクター」コンテナと呼ぶことにします。実際のSTLは効果的なコードを提供しますが、開発者の生活をより簡単にするためのコードも提供しています...いいえ? – jpo38

+0

@ jpo38:はい、そうです。なぜ 'std :: list'にO(N)'演算子[] 'がないのと同じ理由です。実装することはできますが、高速ではありません。 – MSalters

+1

より効率的な 'std :: unordered_set'が既に提供されているため、unique_vectorは提供されません。 'operator =='を書くことができれば、ほとんどの場合、ハッシュ関数を書くことができるという安全な前提です。 – Kevin

1

std::vector使用して。

またはすべての挿入の最後に、std::vector::eraseと組み合わせてstd::uniqueを使用して重複を削除します。

+0

これは私が実際にやっていることです。ちょうどSTLがこれを自動的に行うコンテナを提供していなかったことにちょっと驚きました...私はこの解決策を維持しなければなりません!ありがとう。 – jpo38

+0

@ jpo38私は、std :: setとstd :: unordered_setがあるので、STLがこのようなデータ構造をサポートする理由は見当たりません。 IMHOあなたのものに '演算子'を与えるのは大したことではありません。 – 101010

2

"オブジェクトタイプを考慮してハッシュ関数を書くことはできません(または私は怠け者です)。"

さて、あなたは怠け者ですが、とにかくあなたのために書きます:template<typename T> size_t degenerate_hash(T) { return 0; }

もちろん、すべての値が他のすべての値と衝突するため、O(N)のパフォーマンスが得られることを意味しますが、これは可能な限り最良の結果です。

+0

これは間違いなく良い解決策です!回答ありがとうございます。 – jpo38

関連する問題