22

このように unordered_map を定義する必要があります。関数を定義してこのマップにunordered_map<pair<int, int>, *Foo>渡すための構文は何ですか?hashequal

私はそれにこのオブジェクトを渡そうとしました:

class pairHash{
public:
    long operator()(const pair<int, int> &k) const{
        return k.first * 100 + k.second;
    }
};

そして運がない:

unordered_map<pair<int, int>, int> map = unordered_map<pair<int, int>, int>(1,
*(new pairHash()));

私はそれが何をsize_type_Buskets意味するのか分からないので、私はそれを与えました1。それを行う正しい方法は何ですか?ありがとう。

4

3 に答える 3

45

これは、C++11 では残念ながら省略されています。ブーストには、 という点で答えがありhash_combineます。それらから自由に貼り付けてください!ペアをハッシュする方法は次のとおりです。

template <class T>
inline void hash_combine(std::size_t & seed, const T & v)
{
  std::hash<T> hasher;
  seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}

namespace std
{
  template<typename S, typename T> struct hash<pair<S, T>>
  {
    inline size_t operator()(const pair<S, T> & v) const
    {
      size_t seed = 0;
      ::hash_combine(seed, v.first);
      ::hash_combine(seed, v.second);
      return seed;
    }
  };
}

タプルや範囲など、他の多くのものの基礎として使用できるためhash_combine、たとえば、各メンバーが個別にハッシュ可能である限り、(順序付けられた) コンテナー全体をハッシュできます。

これで、新しいマップを宣言できます:

std::unordered_map<std::pair<int, int>, my_mapped_type> mymap;

自作のハッシャー (統計的特性が良くない) を使用する場合は、テンプレート パラメーターを明示的に指定する必要があります。

std::unordered_map<std::pair<int,int>, int, pairHash> yourmap;

デフォルトではデフォルトで作成されるため、ハッシュ オブジェクトのコピーを指定する必要はありません。

于 2011-08-28T16:31:01.953 に答える
10

ハッシュ関数の戻り値の型はsize_t, notである必要がありますlong(ただし、これはエラーの原因ではありません)。カスタム ハッシュ関数を提供するために示した構文は正しくありません。

上記を適切に機能させるには、equal 述語も指定する必要があります。

#include <unordered_map>
#include <utility>

using namespace std;

class pairHash{
public:
    size_t operator()(const pair<int, int> &k) const{
        return k.first * 100 + k.second;
    }
};

struct pairEquals : binary_function<const pair<int,int>&, const pair<int,int>&, bool> {
  result_type operator()( first_argument_type lhs, second_argument_type rhs ) const
  {
    return (lhs.first == rhs.first) && (lhs.second == rhs.second);
  }
};     

int main()
{
  unordered_map<pair<int, int>, int, pairHash, pairEquals> myMap;

  myMap[make_pair(10,20)] = 100;
  myMap.insert( make_pair(make_pair(100,200), 1000) );
}

編集:は forで定義されている
ため、 equal 述語を定義する必要はありません。比較が異なる方法で行われることが予想される場合にのみ、定義が必要になります。operator==std::pairpairEqualspairEquals

于 2011-08-28T16:32:08.557 に答える