2017-01-28 10 views
4

C++でstl mapを使用することに疑問があります。私はカスタムクラスで地図を使っていることを知っています。マップ作業をするために "<"演算子をオーバーロードする必要があります。しかし、私はそれを意味のある方法でどのように定義しますか?たとえば、私はここで私は非常に自明<演算子をオーバーロードしている次のコードオペレータがカスタムクラスを使用してC++ STLマップをオーバーロードする

#include <iostream> 
#include <map> 
using namespace std; 

struct box{ 
    int e,s,w; 
    box(): e(-1), s(-2), w(-3) 
    {} 

     bool operator< (const box& lhs) const 
     { 
      return e < lhs.e; 
     } 

}; 

int main() { 
    // your code goes here 
    map<box, int> hashtable; 
    box b; 
    hashtable[b] = 1; 
    return 0; 
} 

を持っています。私は次のようにそれをオーバーロードすることもできます

bool operator< (const box& lhs) const 
{ 
    return w+s+e < lhs.e+lhs.s+lhs.w; 
} 

また、他の方法もあります。だから私の質問は、これは、<演算子のオーバーロードは、マップ内の要素にアクセスする時間を削除検索に影響します。私はそれがマップの一部をハッシュすることに影響を及ぼしていることを意味します。もしそうなら、どのような方法でオーバーロードするのが最も良いです<オペレータ。

私の唯一の動機はボックスとintのペア(main関数を参照)を格納することです。これにより、O(log(n))時間にアクセスすることができます。

UPDATE

私はくだらないコンパレータを有する、アクセスに影響を与えるマップの時間を削除するのではなくマップに存在するキーに影響を及ぼさないことを考え出しました。例えば、私のコンパレータは

bool operator< (const box& lhs) const 
{ 
    return e < lhs.e; 
} 

を次れた場合、現在は(1,2,3)と(1,3,4)と(eは、W、S)Iに2つのタプルを言うことができます。私は上記のマップに挿入します。今私は "e"の値に基づいて単独で決定するコンパレータを持っているので、2番目のタプルを拒否します。最後にマップには他のタプルではなく(1,2,3)が含まれます。

コンパレータを書く最も良い方法は、受け入れられた答えの中で@edgarが示唆するように、std::tieを使用することです。

bool operator< (const box& lhs) const 
{ 
    return std::tie(e,w,s) < std::tie(lhs.e,lhs.w,lhs.s); 
} 

タプルの順序が異なる場合でも、この2つのタプルは異なります。私は私の質問でそれの要件を持っていた。たとえば(1,2,3)は(2,1,3)とは異なります。私は、次のコンパレータに、これら両方のタプルは同じ合計を持っているので、ここでも最初のタプルがそれを作っただろう

bool operator< (const box& lhs) const 
{ 
    return e+w+s < lhs.e+lhs.w+lhs.s; 
} 

ので、もう一度よくないコンパレータを使用していました。

+3

FYI、STD ::マップはハッシュテーブルではなく、ハッシュを使用していません。そのためには、std :: unordered_mapが必要です。 –

+0

'e'、' w'、 's'のような変数名では、' operator'がこのクラスに対して何を意味するのかを理解することは容易ではありません。 –

+0

@PaulRooney、私のケースでは、私はボックスの積み重ねの問題を解決していました。それは長さ、息、箱の高さでした。私はネクタイによって解決される異なったタプルがあったらそれらを木に入れたいと思った。 – paramvir

答えて

4

だから私の質問は、この、<演算子のオーバーロード、 検索に影響を与え、マップ内の要素にアクセスする時間を削除しています。

いいえ、検索、削除、およびアクセスの要素は対数時間で実行されます。

これは、地図の一部をハッシュすることに影響します。

のstd ::マップのstd :: unordered_mapではないので、ここにはハッシュはありません。

もしそうなら、<オペレータをオーバーロードする最良の方法は何ですか。

私は、標準的な方法は、今std::tieを使用することであることとします

bool operator<(const box& lhs) const 
{ 
    return std::tie(e, s, w) < std::tie(lhs.e, lhs.s, lhs.w); 
} 
+0

回答のためにedgarに感謝..私の演算子オーバーロードの方法と提案されたものは、ツリーの時間を削除してアクセスに影響を与えません...そうですか? – paramvir

+0

@paramvirはい、間違いなく。すべての方法の詳細については、http://en.cppreference.com/w/cpp/container/mapを参照してください。 –

+0

私にネクタイを紹介してくれてありがとう@edgar ... – paramvir

1

std::mapはハッシュマップではありません。バイナリツリーです。

operator<は、ツリーにアクセスするたびに、ルックアップステップごとに1回呼び出されます。したがって、明らかに複雑さがパフォーマンスに影響します(オーバーヘッドを除いて、たとえばstd::mapでの検索のコストはoperator<のコストに比例します)。

std::unordered_mapはハッシュマップです。しかし、そのためには、std::hash<box>std::equal_to<box>(ハッシングと等価ファンクタ)を実装する必要があります。その場合、operator<は使用されません。

+0

あなたは "パフォーマンスに影響を与える"部分を詳しく説明できますか?ドキュメントでは、ログラミック時間であると言います。 – paramvir

+0

@paramvir挿入、削除、または削除のたびに 'operator <' O(ln(n))参照 –

関連する問題