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