【问题标题】:User defined hash function for unordered map用户定义的无序映射散列函数
【发布时间】:2013-04-13 15:29:58
【问题描述】:

我已经为 unrorderd_map 定义了我自己的哈希函数。但我无法使用 find 功能在容器中搜索。我尝试在散列函数中使用打印语句进行调试,它生成的散列值与插入键/值时生成的散列值相同。如果有人能指出错误,那就太好了。我在 Windows 上使用 Eclipse IDE,并且正在使用 -std=c++11

进行编译
typedef struct tree node;

struct tree
{
int id;
node *left;
node *right;
};

class OwnHash
{
public:
    std::size_t operator() (const node *c) const
    {
       cout << "Inside_OwnHash: " <<std::hash<int>()(c->id) + std::hash<node *>()(c->left) + std::hash<node *>()(c->right) << endl;
       return std::hash<int>()(c->id) + std::hash<node *>()(c->left) + std::hash<node *>()(c->right);
    }
};

int main()
{
std::unordered_map<node *,node *,OwnHash> ut;

node * one = new node;
one->id = -1;
one->left = nullptr;
one->right = nullptr;
ut.insert({one,one});

node * zero = new node;
zero->id = 0;
zero->left = NULL;
zero->right = NULL;
ut.insert({zero,zero});

node * cur = new node;
cur->id = 5;
cur->left = zero;
cur->right = one;
ut.insert({cur,cur});

for (auto& elem : ut)
{
    std::cout << "key: " << elem.first << "\t" << "value: " << elem.second->id << std::endl;
}

node * parse = new node;
parse->id = 5;
parse->left = zero;
parse->right = one;

std::unordered_map<node *,node *>::const_iterator got1 = ut.find (parse);

if ( got1 == ut.end() )
    std::cout << "not found";
else
    std::cout << got1->first << " is " << got1->second->id << std::endl;

return EXIT_SUCCESS;
}

    Output:
    Inside_OwnHash: 4294967295
    Inside_OwnHash: 0
    Inside_OwnHash: 22946517
    key: 0xaf11b0   value: 5
    key: 0xaf1180   value: 0
    key: 0xaf1150   value: -1
    Inside_OwnHash: 22946517
    not found

【问题讨论】:

  • 除非出于教育/学习目的...只是一个问题:您是在调试模式下对 std c++ 容器的速度和效率提出疑问的第一千个吗?您可能有充分的理由重新实现哈希表,这没问题。只是一个反射性问题。
  • 如果可以的话,我会使用内置的哈希函数。但出于特定原因,我需要定义我自己的。我正在使用它来构建二元决策图。我发布的代码只是为了模仿我需要它的场景。
  • @StephaneRolland 该代码使用与标准哈希函数不同的语义 - 它根据指针指向的对象的内容对指针进行哈希处理。这是您自己的哈希的一个非常正当的理由。我在问题中没有看到对std 效率的任何担忧。

标签: c++ hash unordered-map


【解决方案1】:

哈希还不够,还得实现相等比较!

散列必须是一个函数,如果项目相等,则它们的散列相等。但是由于项目可能是任意复杂的,并且哈希结果只是 size_t,因此相反的含义不成立,也不能成立。所以要找到确切的元素,你也需要一个相等比较。

查找时,哈希函数将其指向正确的“桶”,但其中可能有多个元素,或者那里可能有一个元素,但不是您要查找的那个。因此,它会获取存储桶中的所有元素,并将每个元素与您正在搜索的元素进行比较。

现在您提供了一个哈希函数,但没有提供相等比较器。所以它使用默认值,即operator==,用于定义为比较地址的指针。并且地址相等。您需要提供比较值的相等函子。

【讨论】:

  • 正确。太感谢了。这很有意义,而且效果也很好。
猜你喜欢
  • 2013-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-07
  • 1970-01-01
  • 2011-11-19
  • 2014-10-30
  • 1970-01-01
相关资源
最近更新 更多