【问题标题】:C++ Hash function for string in unordered_mapunordered_map 中字符串的 C++ 哈希函数
【发布时间】:2013-03-13 19:30:08
【问题描述】:

似乎 C++ 在标准库中没有字符串的散列函数。这是真的吗?

什么是在 unordered_map 中使用字符串作为键的工作示例,可以与任何 c++ 编译器一起使用?

【问题讨论】:

  • 我很好奇是什么让您认为标准库(至少是支持 unordered_map 的库)不支持 std::string 的哈希函数?
  • “错误 C2338:C++ 标准不提供这种类型的哈希。”当我尝试使用字符串时。
  • 也许这个 SO 答案可能与您发生的事情有关:stackoverflow.com/a/11157019/12711 您是否直接使用basic_string<> 而不是通过std:string typedef?您可能可以将basic_string<> 用于某些目的而不会出现编译器错误,因为另一个标头恰好正在拉入xstring(它给您basic_string<>,但不是std::hash<string>
  • 所以底线是 - 如果你想在 unordered_map<> 中使用字符串,请确保你有一个 #include <string> - 实际上,任何时候你都在使用 std::string。不幸的是,由于其他包含的副作用,编译器有时会让您在没有包含的情况下逃脱。然后,当您添加一个实际需要 string 标头的使用时,您会从编译器中得到一个神秘的、非显而易见的错误。
  • 有时发生在我身上的是 IDE 错误地将我的 #include <unordered_map> 更改为 #include <bits/unordered_map.h>。因此,请确保您包含了正确的库。

标签: c++ string c++11 key unordered-map


【解决方案1】:

C++ STL 为各种字符串类提供模板specializationsstd::hash。您可以指定std::string 作为std::unordered_map 的键类型:

#include <string>
#include <unordered_map>

int main()
{
    std::unordered_map<std::string, int> map;
    map["string"] = 10;
    return 0;
}

【讨论】:

  • 这是来自类型构造函数的隐式行为,不是吗?当您已经有 std::unordered_map&lt;std::string&gt; 时指定 std::hash&lt;std::string&gt;&gt; 只是多余的。
  • 我认为这应该用选项“-std=c++0x”编译?
  • @Bloodmoon,是的(我会说,-std=c++11),unordered_map 是 C++11 功能。
【解决方案2】:

我今天遇到了这个问题(实际上是wstring,而不是string,但它是相同的交易):使用wstring 作为unordered_map 中的键会生成一个关于没有可用哈希函数的错误输入。

我的解决方案是添加:

#include <string>

信不信由你,没有#include 指令,我仍然可以使用wstring 类型,但显然没有像哈希这样的辅助功能。只需添加上面的包含即可修复它。

【讨论】:

  • 这个答案最直接地解决了我的问题(不包括&lt;string&gt;
【解决方案3】:

其实有std::hash&lt;std::string&gt;

但是你可以如何使用另一个哈希函数:

struct StringHasher {
    size_t operator()(const std::string& t) const {
          //calculate hash here.
    }
}

unordered_map<std::string, ValueType, StringHasher>

【讨论】:

    【解决方案4】:

    如果您有一个CustomType 并且您想插入 STL 基础架构,那么您可以这样做。

    namespace std
    {
    //namespace tr1
    //{
        // Specializations for unordered containers
    
        template <>
        struct hash<CustomType> : public unary_function<CustomType, size_t>
        {
            size_t operator()(const CustomType& value) const
            {
                return 0;
            }
        };
    
    //} // namespace tr1
    
    template <>
    struct equal_to<CustomType> : public unary_function<CustomType, bool>
    {
        bool operator()(const CustomType& x, const CustomType& y) const
        {
            return false;
        }
    };
    
    } // namespace std
    

    如果你想创建一个std::unordered_map&lt;CustomType&gt;,STL 将找到hashequal_to 函数,而无需你对模板做更多的事情。这就是我喜欢编写支持无序数据结构的自定义相等比较器的方式。

    【讨论】:

    • 注意:unary_function 已被弃用。最好自己提供 typedefs result_type 和 argument_type。
    【解决方案5】:

    在我的情况下,这真的很让人分心。

    我有一个 X 类型,我为 const& X 实现了散列,并在某处使用了它

    std::unordered_map<const X, int> m_map;
    

    然后我想要另一张地图,其中的键是 X 类型的并且做了:

    std::unordered_map<X, int> map_x;
    

    注意第二种情况下constLACK

    【讨论】:

      猜你喜欢
      • 2011-11-05
      • 1970-01-01
      • 2012-03-21
      • 2015-03-09
      相关资源
      最近更新 更多