【问题标题】:What should I pass to unordered_map's bucket count argument if I just want to specify a hash function?如果我只想指定一个哈希函数,我应该将什么传递给 unordered_map 的存储桶计数参数?
【发布时间】:2012-12-20 04:59:17
【问题描述】:

C++11 的unordered_map 的默认构造函数如下所示:

explicit unordered_map( size_type bucket_count = /*implementation-defined*/,
                    const hasher& hash = hasher(),
                    const key_equal& equal = key_equal(),
                    const allocator_type& alloc = allocator_type() );

我想创建一个带有自定义哈希函数的unordered_map,但它是构造函数的第二个参数。

我应该使用多少桶数?我可以使用一个神奇的值来告诉容器自己决定吗?否则,是否有一种启发式方法可以用来根据我希望我的地图包含的键数之类的东西来猜测一个好的桶数?我应该关心吗?

【问题讨论】:

    标签: c++ stl c++11 unordered-map


    【解决方案1】:

    我不会太担心。

    容器保证存储桶计数将至少您提供的值,即如果需要它会增加它。您可以将零作为存储桶计数传递,实现将执行类似std::max(count, 10) 的操作并覆盖零值,或者它只会在第一次插入时重新散列。

    另一种选择是从默认构造的对象中复制值:

    H hasher;
    unordered_map<K,T,H,P> m{ unordered_map<K,T,H,P>{}.bucket_count(), hasher };
    

    这会将存储桶计数设置为实现的默认值(但确实需要 H 哈希函数类型为 DefaultConstructible。)

    FWIW GCC 的 unordered_map 使用 10 作为您展示的构造函数的默认值(所以这可能也是一个合理的默认值),并使用 0 作为构造函数采用一对迭代器或 initializer_list

    【讨论】:

    • 好把戏。没有考虑到这一点。感谢您的调查。
    • 你确定std::min?如果您需要至少 10 个元素,则公式为 std::max(count, 10)
    • 问题和答案已复制/粘贴到https://coderedirect.com,没有参考...
    • @Jarod42 那个网站是什么?!我在那里找到了其他几个 SO 答案的副本 - 包括我自己的一个,我叫 Alex Chernilov :-)
    • @TedLyngmo:我不知道,偶然发现的。我没有找到 SO 和那个网站之间的关系,所以警告。 (我在 SO 上找到的唯一参考是 answer which references answer from that site)。
    【解决方案2】:

    unordered_map 的模板参数之一是哈希函数。如果您在此处指定哈希函数对象,则可以将构造函数参数保留为默认设置。

    【讨论】:

    • 虽然我同意你的观点,但你可以将哈希器的 type 指定为模板参数,但仍需要在构造时为 unordered_map 提供特定的哈希器对象如果您想做一些花哨的事情(例如,如果您的散列器是一个通用的散列函数系列,并且您需要指定要使用其中的哪一个散列函数)。
    • Rapptz 在 C++ 聊天中建议。它确实 为我的目的工作,因为我只是要传递一个函数指针(所以将它包装在一个结构中并不是什么大事),这绝对值得一提,但正如@templatetypedef 所说,它没有并不能真正帮助那些真正需要计算桶数的人。
    猜你喜欢
    • 1970-01-01
    • 2020-08-23
    • 1970-01-01
    • 2021-02-14
    • 2014-11-11
    • 2012-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多