C++ 如何改进我的哈希算法 stper**页; int表大小; 结构人{ 字符串名; 智力年龄; 弦故乡; }; void fonk1(整数个桶) { pages=新stper*[NumberOfBucket](); tableSize=numberofbucket; } int hashPerson(Person和Person) { int hashVal=0; 对于(int i=0;i

C++ 如何改进我的哈希算法 stper**页; int表大小; 结构人{ 字符串名; 智力年龄; 弦故乡; }; void fonk1(整数个桶) { pages=新stper*[NumberOfBucket](); tableSize=numberofbucket; } int hashPerson(Person和Person) { int hashVal=0; 对于(int i=0;i,c++,algorithm,hash,C++,Algorithm,Hash,大家好,我是散列新手。我的散列函数在上面的hashPerson函数中,您可以看到有三个键。我的函数是一个很好的散列算法吗?如何改进函数并减少冲突次数?(如果有语法错误,请忽略)我有一些建议: 使用unsigned代替int。根据我的经验,这已经被证明表现得更好,因为当未签名溢出时,它仍然保持非负(否则可能会导致大问题-你会得到一个负指数和…崩溃),并且它还导致碰撞率降低(经经验证明)。此外,函数应该返回表中的索引,因此值不带符号是很自然的-索引不能为负 在添加年龄时,将hashVal乘以某物。我

大家好,我是散列新手。我的散列函数在上面的hashPerson函数中,您可以看到有三个键。我的函数是一个很好的散列算法吗?如何改进函数并减少冲突次数?(如果有语法错误,请忽略)

我有一些建议:

  • 使用
    unsigned
    代替
    int
    。根据我的经验,这已经被证明表现得更好,因为当未签名溢出时,它仍然保持非负(否则可能会导致大问题-你会得到一个负指数和…崩溃),并且它还导致碰撞率降低(经经验证明)。此外,函数应该返回表中的索引,因此值不带符号是很自然的-索引不能为负

  • 在添加年龄时,将hashVal乘以某物。我建议的值大于任何可能的年龄,例如200岁

  • 你永远不会说什么是
    tableSize
    ,但我建议你使用一些大的(尽可能大的)素数,再次降低冲突率


  • 您可以使用
    std::hash
    为基本组件生成良好的哈希值。你可以找到一些例子和解释


    如果您安装了boost的一个版本,您可能会发现,
    boost::hash\u combine
    满足您的需要。您可以通过一个很好的示例找到boost的文档。

    到目前为止,您使用的哈希函数有什么问题?你有任何理由怀疑你需要改变它吗?你的哈希函数很好。但是你使用C++,为什么不使用你的散列上的STL?不能区分某人的名字的结尾和他们家乡的开始。杰西·杰克逊(无位置)和杰克逊镇上的杰西将发生碰撞。@rrenaud,这不太正确。一个是“Jesse Jackson”,另一个是“JesseJackson”。但是,根据一般原则,最好对不同的字段使用不同的乘数。
    stper** pages;
    int tableSize;    
    struct Person{
    
        string name; 
        int age;    
        string homeTown;
    };
    
    
    void fonk1 (int numberOfBuckets)
    {
        pages = new stper*[numberOfBuckets]();
        tableSize = numberOfBuckets;
    } 
    
       int hashPerson(Person& person)
       {
        int hashVal = 0;
        for (int i=0; i < (person.getName()).length() ; i++)
            hashVal = 37*hashVal + (person.getName())[i];
    
        for (int i=0; i < (person.getHomeTown()).length() ; i++)
            hashVal = 37*hashVal + (person.getHomeTown())[i];   
        hashVal+= person.getAge();  
    
        hashVal %= tableSize;
        if(hashVal < 0)
            hashVal += tableSize;
        return hashVal;
       }