2016-11-18 148 views
0

我已经在C++中实现了哈希映射。 一切工作正常,除了哈希函数。如何实现各种类型的密钥的哈希函数?

我有一个模板类的元素,以便我可以使用各种变量类型的哈希映射。 这是我的代码元素。

template <class KeyType, class ValType> 
class MapElem 
{ 
public: 
    typedef KeyType ktype; 
    typedef ValType vtype; 

    KeyType key; 
    ValType val; 

    MapElem* link; // singly linked list 
}; 

和散列函数代码。

template <class HashMapElemType> 
unsigned int 
HashMap<HashMapElemType>::hashfunction(const KeyType k) 
{ 
    unsigned int hashIndex = 0; 



    if (typeid(KeyType).name() == typeid(std::string).name()) 
    { 
     unsigned int hashIndex = 0; 

     const char* c = k.c_str(); 

     unsigned int i = 0; 
     int index = 0; 
     int shift = 0; 

     while (c[index] != '\0') 
     { 
      if (shift == 32) 
       shift = 0; 
      i += ((int) c[index++]) << shift; 
      shift += 8; 
     } 

     hashIndex = i; 
    } 
    else if (typeid(KeyType).name() == typeid(float).name()) 
    { 
     float f = k; 
     hashIndex = (unsigned int) f; 
    } 
    else if (typeid(KeyType).name() == typeid(int).name()) 
    { 
     int i = k; 
     hashIndex = (unsigned int) i; 
    } 
    else 
    { 
     hashIndex = k; 
    } 

    hashIndex = hashIndex % divisor; 

    return hashIndex; 
} 

而且还有在散列函数型铸造编译错误。我明白为什么发生错误,但我不知道如何解决它。 我想知道如何从不同类型的键值中获取散列值。

哦,这是错误 enter image description here

+1

那么......哪里出错? – George

+0

您不能只是将任意类型转换为某种东西,因为typeid表示它有一个名称。如果语句在运行时运行 - 它们不会在编译时影响类型系统。所有这些代码路径必须为每个键类型编译,并且它们并不总是有效的。你可能会想做部分专用的函子。或者也许你的错误是完全不同的...... – xaxxon

回答

0

你的散列函数应该是关键类型的模板功能,你的容器类外实现。 然后,您可以针对您实际使用哈希映射的每个键类型专门化模板函数。 这将类型检查从运行时转换为编译时,使其更快更安全。

// hash function prototype, no implementation 
template<typename T> unsigned int CalculateHash(const T& v); 

// hash function specialization for std::string 
template<> unsigned int CalculateHash(const std::string& v) 
{ 
    // your hash function for std::string ... 
} 

在你的容器实现中,你可以使用通用哈希函数为你的密钥生成一个哈希值。

template <class HashMapElemType> 
unsigned int HashMap<HashMapElemType>::hashfunction(const KeyType& k) 
{ 
    // delegate to global hash function template 
    return ::CalculateHash<KeyType>(k); 
} 
+0

它确实有帮助,并且运作良好。非常感谢你。 – Uni

+0

不客气。我很高兴它有帮助。 – smocoder