2009-04-10 2 views
19

Мне нужно сопоставить пару long long с double, но я не уверен, какую функцию использовать. Каждая пара может состоять из любых двух чисел, хотя на практике они обычно будут числами между 0 и примерно 100 (но опять же, это не гарантируется).Функция хэша для пары длинного длинного?

Here - это документация tr1::unordered_map. Я начал вот так:

typedef long long Int; 
typedef std::pair<Int, Int> IntPair; 

struct IntPairHash { 
    size_t operator(const IntPair& p) const { 
    return ...; // how to hash the pair? 
    } 
}; 

struct IntPairEqual { 
    bool operator(const IntPair& a, const IntPair& b) const { 
    return a.first == b.first 
     && a.second == b.second; 
    } 
}; 

tr1::unordered_map<IntPair, double, IntPairHash, IntPairEqual> myMap; 

В общем, я никогда не знаю, какую функцию использовать. Какая хорошая хэш-функция общего назначения?

+21

Рассматривали ли вы с помощью одного или нескольких из следующих общего назначения хэш-функции: http://www.partow.net/programming/hashfunctions/index.html они очень быстро и эффективно , – 2011-01-23 10:11:34

ответ

1

Вам действительно нужна карта на основе хэша? Общая карта, основанная на двоичном дереве, будет работать нормально, пока сложность гарантирует ее работу над проблемой, которую вы решаете.

+0

Хм, хорошо, в этом случае, как бы выглядела функция сравнения, которая сравнивает две IntPairs (функция 'less' для IntPairs)? – 2009-04-10 15:55:13

+0

@Frank: простейшая форма: (a.first

+0

Этот файл (a.first 2009-04-10 17:34:31

10

boost::hash Форма функциональная библиотека.

или написать свой собственный. простейшая версия = пара.первый * max_second_value + pair.second

+0

+1 для функции. ссылка на boost :: hash была бы замечательной. –

11

Естественный способ хэш-пары состоит в том, чтобы каким-то образом объединить хэши своих компонентов. Самый простой способ это просто с исключающим:

namespace std { 
namespace tr1 { 

template<typename a, typename b> 
struct hash< std::pair<a, b> > { 
private: 
    const hash<a> ah; 
    const hash<b> bh; 
public: 
    hash() : ah(), bh() {} 
    size_t operator()(const std::pair<a, b> &p) const { 
     return ah(p.first)^bh(p.second); 
    } 
}; 

}} // namespaces 

Обратите внимание, что это хэш пару, как (1,1) или (2,2) все к нулю, так что вы можете использовать некоторые более сложный способ объединить хэшей частей, в зависимости от ваших данных. Подталкивания делает что-то вроде этого:

size_t seed = ah(p.first); 
return bh(p.second) + 0x9e3779b9 + (seed<<6) + (seed>>2); 
+1

Пожалуйста, внимательно прочитайте boost hash.hpp. Bost делает что-то вроде этого: seed = hash (first) + 0x9e3779b9 + (seed <<6) + (seed>> 2); return seed^(hash (second) + 0x9e3779b9 + (seed <<6) + (seed>> 2)); – velkyel