如何在C ++中实现通用哈希函数

时间:2013-04-26 19:19:23

标签: c++ string algorithm hashtable

我试图通过模板在C ++中实现HashTable。 这是签名:

template<class T1, class T2>
class HashTable {

public:
void add(T1 a, T2 b);

void hashFunction(T1 key, T2 value)
{

// how to implement this function using key as a generic 
// we need to know the object type of key

}
};

因此,我无法推进涉及通用密钥的实现。

在Java中,我可以轻松地将密钥转换为字符串,然后很高兴将密钥的哈希实现为字符串。但是,在C ++中,我所知道的是有一个RTTI概念可以动态地将对象转换为所需的对象。

如果这种方法完全正确,如何实现动态转换?

如果在这种情况下使用模板不是实现泛型的正确方法,那么请建议一些更好的方法。

2 个答案:

答案 0 :(得分:10)

您通常会使用std::hash,并让类型实现者根据需要专门化该模板。

size_t key_hash = std::hash<T1>()(key);

对于您给出的任何随机类型,您无法一般地实现哈希函数。如果两个对象相等,则它们的哈希码必须相同。您可以通过哈希函数简单地运行对象的原始内存,但类型可能实现忽略某些对象数据(例如,同步对象)的operator==重载。在这种情况下,您可能(并且非常容易)为相同的对象返回不同的哈希值。

答案 1 :(得分:4)

奇怪的是,你想要哈希键和值。你之后如何才能通过钥匙获得价值?

如果您正在使用C ++ 11,那么好主意是使用为某些类型(整数,字符串,指针)提供的std::hash<T1>,并且可能专门用于其他类。此外,允许使用第三个模板参数类进行更改是个好主意。了解unordered_map的完成方式

template<typename K, typename V, typename H = std::hash<T>>
class HashTable {
   //...
   void hashFunction(const T1& key) {
        hash = H()(key);
        //process hash somehow, probably you need get reminder after division to number of buckets or something same
        return hash % size;
   }
}

似乎不可能编写自己的哈希,对大多数类型都可以正常工作,因为可能会以某种复杂的方式覆盖相等运算符