【问题标题】:unordered map without hashing没有散​​列的无序映射
【发布时间】:2013-12-09 03:51:11
【问题描述】:

我想使用类似于 std::map 的结构,但没有排序,我不需要排序,而且我的密钥非常大,所以“小于”比较需要时间。 所以,我看到了 unordered_map 但它有一个哈希模板参数,那么,如何在没有哈希的情况下使用 unordered_map?我真的需要构建自己的容器吗?

这个问题也适用于 std::set。

编辑 一些答案建议创建我自己的哈希,但我不能这样做,我应该在这里指定它。密钥包含浮点数据,因此散列它是一个非常糟糕的主意。我需要直接比较 (std::equal_to)。

【问题讨论】:

  • 你希望这个容器能做什么? std::hash_map 等提供基于散列的快速查找。如果您不想要散列,那么您将无法快速查找,或者您必须提供一些其他机制。
  • 听起来您想将键映射到某个值。您如何设想完成映射? std::map<...> 使用小于关系来定位对象。排序只是脱离了它的内部结构。无序容器使用散列而不是排序来定位对象。如果你不想要,你需要描述你想象的钥匙是如何被发现的......
  • std::unordered_map 可能非常适合您的要求。考虑专注于如何成功地将您自己的类型用作容器键。
  • @Captain Obvlious 实际上我已经“找到”了如何将我的类型作为键。在 std::map 的情况下, operator

标签: c++ map stl


【解决方案1】:

创建您自己的哈希,通过在您的密钥字段上组合std::hash 的重载轻松完成。

cppreference example(与上一个链接相同)非常好(即使您不需要模板的东西):

struct S
{
    std::string first_name;
    std::string last_name;
}; 

template <class T>
class MyHash;

template<>
class MyHash<S>
{
public:
    std::size_t operator()(S const& s) const 
    {
        std::size_t h1 = std::hash<std::string>()(s.first_name);
        std::size_t h2 = std::hash<std::string>()(s.last_name);
        return h1 ^ (h2 << 1);
    }
};

之后就可以在std::unorderd_map中使用了:

std::unordered_map<S, Value, MyHash<S>> the_map;

顺便std::unordered_set也需要一个哈希。

【讨论】:

  • @LINK2012 哈希是在floatdouble 上完成的……这甚至是由std::hash 函数提供的……哈希的目的只是为了精细化存储桶,不多不少。
  • 但是浮点的 std::hash 只是散列它的位(至少在 GNU 实现中),例如 5.12 有“许多”方式可以在 IEEE 表示中表示
  • @LINK2012 Are you sure ?
  • 我可能没有准确表达我的观点,我的意思是something like this
  • @LINK2012 他们不是在寻找元素的完全匹配。您将在比较运算符上遇到问题。如果您在比较运算符上处理它,请不要散列浮点数。
【解决方案2】:

在声明 unordered_map 之前,您需要为您的键指定哈希对象。

    namespace std
    {
    template <>
    class hash<Key>
    {
    public:
      size_t operator()(const Key &) const
      {
        // ... your hash function for Key object ...

      }
    };
    }

    std::unordered_map<Key, Value> myMap;

例如,如果我想让你用作密钥对:

    namespace std
    {
    class hash<pair<string, int>>
    {
    public:
      size_t operator()(const pair<string, int> &s) const
      {
        size_t h1 = hash<string>()(s.first);
        size_t h2 = hash<int>()(s.second);
        return h1 ^ (h2 << 1);
      }
    };
    }

    unordered_map<pair<string, int>, string> myMap;

【讨论】:

    猜你喜欢
    • 2011-11-19
    • 2014-10-30
    • 2013-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多