C++ C++;带有自定义哈希问题的无序_映射
我正在尝试编写一个自定义哈希函数,用于无序的_映射。我可以插入项并遍历它们,但无法使用at()、find()或operator[]函数查找项C++ C++;带有自定义哈希问题的无序_映射,c++,hash,unordered-map,C++,Hash,Unordered Map,我正在尝试编写一个自定义哈希函数,用于无序的_映射。我可以插入项并遍历它们,但无法使用at()、find()或operator[]函数查找项 #include <cstddef> #include <iostream> #include <functional> #include <random> #include <unordered_map> #include <stdint.h> #include <stdio
#include <cstddef>
#include <iostream>
#include <functional>
#include <random>
#include <unordered_map>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#define JHASH_GOLDEN_RATIO 0x9e3779b9
using namespace std;
#define __jhash_mix(a, b, c) \
{ \
a -= b; a -= c; a ^= (c>>13); \
b -= c; b -= a; b ^= (a<<8); \
c -= a; c -= b; c ^= (b>>13); \
a -= b; a -= c; a ^= (c>>12); \
b -= c; b -= a; b ^= (a<<16); \
c -= a; c -= b; c ^= (b>>5); \
a -= b; a -= c; a ^= (c>>3); \
b -= c; b -= a; b ^= (a<<10); \
c -= a; c -= b; c ^= (b>>15); \
}
uint32_t
jhash_3words (uint32_t a, uint32_t b, uint32_t c, uint32_t initval)
{
a += JHASH_GOLDEN_RATIO;
b += JHASH_GOLDEN_RATIO;
c += initval;
__jhash_mix (a, b, c);
return c;
}
size_t jenkins_hash(const uint32_t &num){
return (size_t) jhash_3words (num, 0, 0, rand());
}
int main(){
std::unordered_map<uint32_t, char, std::function<decltype(jenkins_hash)>> ids(0, jenkins_hash );
ids[(uint32_t) 42341] = 'g';
ids[(uint32_t) 2232] = 'b';
ids[(uint32_t) 7556] = 'q';
for ( auto it = ids.begin(); it != ids.end(); ++it ){
std::cout << "Element " << it->first << " " << it->second << std::endl;
}
std::cout << ids.size() << std::endl;
printf("%c\n", ids.find(7556)->second);
return 0;
}
我的问题是
- 为什么会产生断层
- 为什么at()和运算符[]什么也不返回,而find()呢 断层
size_t jenkins_hash(const uint32_t &num){
return (size_t) jhash_3words (num, 0, 0, rand());
}
由于散列函数包含一个随机元素,因此对两次7556
进行散列将产生不同的散列值。这意味着find
执行的查找无法找到任何内容,实际上返回的是ids.end()
,您不应该取消引用
下面是您应该如何使用find()
:
与您的问题完全无关,但请避免使用带有两个前导下划线的符号(如
\uuuuujhash\umix
),因为这些符号是为“实现”(编译器和标准库)保留的。有关信息,请参见ids.find(7556)->second
中的.idfind
,当您尝试访问其second
时,这将触发seg fault您的哈希不确定,请尝试了解哈希方法和“代码> unOrdEdjPMAX <代码>在尝试插入自定义Hason另一个无关注释之前所做的工作,请避免在C++中使用C风格的转换。如果你需要这样做,那么你很可能是做错了什么。至于你的问题,请阅读@PasserBy的评论,并试着理解“不确定性”是什么意思。提示:您认为rand
函数的作用是什么?如果计算中混入了随机成分,那么两个相同的键怎么会生成相同的散列呢?哇,这完全有道理。变为一个常数,它工作得很好。谢谢
size_t jenkins_hash(const uint32_t &num){
return (size_t) jhash_3words (num, 0, 0, rand());
}
auto found = ids.find(7556);
if(found != ids.end()) {
printf("%c\n", found->second);
}