【问题标题】:Making a hash table of iterators in C++在 C++ 中制作迭代器的哈希表
【发布时间】:2013-06-21 08:29:38
【问题描述】:

我试图通过散列一些节点指针来加速特定的链表操作。这是我正在使用的代码:

unordered_set< typename list< int >::iterator > myhashset;

在 Visual Studio 2012 中,我收到“错误 C2338:C++ 标准不为此类型提供散列”,因为编译器不知道如何散列迭代器。因此,我需要为列表迭代器实现自己的哈希函数,如下所示:

struct X{int i,j,k;};

struct hash_X{
  size_t operator()(const X &x) const{
    return hash<int>()(x.i) ^ hash<int>()(x.j) ^ hash<int>()(x.k);
  }
};

(wikipedia reference)

我无法确定迭代器的哪些成员保证唯一性(因此,我想要散列的成员)。另一个问题是这些成员可能是私有的。

想到的一个解决方案是重新实现和 list::iterator,但这似乎是一种 hack,并且引入了更多需要维护的代码。

【问题讨论】:

  • 那不是迭代器!你的未来,笼罩着的是。迭代器,困惑的是。散列 [iterators] 导致愤怒,愤怒导致仇恨,仇恨导致 gdb。
  • @kfsone:我也不是特别喜欢迭代器(在实现之后)。有时我会怀念编写好旧 C 的日子。不过,我看不到 C++ 中迭代器的任何替代品。
  • 选项 a) 我关闭了我的 stackoverflow 帐户,选项 b) 我回复“与 (*youIt) 合作”。

标签: c++ hash c++11 iterator


【解决方案1】:

使用迭代器引用的元素的地址。

struct list_iterator_hash {
    size_t operator()(const list<int>::iterator &i) const {
        return hash<int*>()(&*i);
    }
};

但这仅适用于可取消引用的迭代器,不适用于 end()list&lt;int&gt;::iterator()

【讨论】:

  • @KonradRudolph 迭代器可以按值传递,但地址是它指向的东西。
  • 你需要更多的括号吗? return hash&lt;int*&gt;()(&amp;*i); 对我来说效果更好。
  • @Eyal 是的,你知道。我通过编辑添加了它。
【解决方案2】:

您可以使用指向元素的指针来代替迭代器。假设您有一个结构列表MyStruct。你可以使用

unordered_set<MyStruct*> myhashset;

并且 C++ 标准库已经实现了std::hash for any pointer

因此,如果您需要插入或搜索listIt,请使用&amp;(*listIt),它将获得MyStruct* 类型的指针。

【讨论】:

    猜你喜欢
    • 2015-10-24
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 2016-03-28
    • 2021-12-25
    • 2018-08-23
    • 1970-01-01
    • 2012-01-30
    相关资源
    最近更新 更多