2016-04-12 6 views
1

私がしようとしているのは、素数を使ってアナグラムのハッシュを作成することです。しかし、==演算子のために余分なstruct keyを作成しなければならないのはやや不便です。 std :: stringの既存の==をオーバーロードするための回避策がありますか?ハッシュのために==ロジックstd :: stringを上書きすることはできますか?

#include <string> 
#include <unordered_map> 
#include <cstddef> 
#include <iostream> 


using namespace std; 

int F[26] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 
      31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 
      73, 79, 83, 89, 97, 101}; 

size_t f(const string &s) { 
    size_t r = 1; 
    for (auto c : s) { 
    r *= F[c - 'a'] % 9999997; 
    } 
    return r; 
} 

// this struct seemed redundant! 
struct key { 
    const string s; 

    key(const string s) 
    :s(s) {} 

    bool operator ==(const key &k) const { 
    return f(s) == f(k.s); 
    } 
}; 

struct hasher { 
    size_t operator()(const key &k) const { 
    return f(k.s); 
    } 
}; 

int main() { 
    unordered_map<key, int, hasher> cnt; 
    cnt[key{"ab"}]++; 
    cnt[key{"ba"}]++; 
    cout << cnt[key{"ab"}] << endl; 
} 
+0

継承を使用します。 – tomascapek

+1

@RainbowTom:しないでください。 'std :: string'は基本クラスとしてではなく、値クラスとして設計されています。 C++ **は 'int'から継承するのを止め、' ** std :: string'を継承することを止めるべきです**。 – MSalters

+0

@MSalters毎日スマートに、ありがとう! – tomascapek

答えて

7

unordered_map

template< 
    class Key, 
    class T, 
    class Hash = std::hash<Key>, 
    class KeyEqual = std::equal_to<Key>, 
    class Allocator = std::allocator<std::pair<const Key, T>> 
> class unordered_map; 

として宣言されている::文字列をSTDから派生する独自のクラスを作成し、その新しいクラスにご過負荷演算子を追加第4のテンプレートパラメータとしての述語。

+0

大変感謝しています。このことを全く知らない。 – Chan

+0

私は ''をインクルードリストで見たことがあり、それ以上読むことはありません。 > _ < – bipll

+0

@bipll私は質問のインクルードをきれいにしました。 – juanchopanza

-3

あなたがあなた自身の平等を置き換えることができますので、

+2

これは危険です。基本クラスは仮想関数を持たないので、 'std :: string'を受け入れるインターフェイスに渡した場合、間違った等価が使用されます –

関連する問題