【问题标题】:Hashing a string to an integer in c++在c ++中将字符串散列为整数
【发布时间】:2013-04-11 02:44:50
【问题描述】:

我试图弄清楚字符串到整数的转换过程。我们正在做一个带有散列的程序,其中要散列的键值是一个状态的名称。根据我的研究,似乎 atoi() 不起作用。

我需要分解单词的每个字母并单独转换吗?我使用 ASCII 吗?我是不是完全走错了方向?

我很迷茫,所以任何信息都会很棒。谢谢!

【问题讨论】:

  • 你可以实现类似于 java.lang.String 的hashcode 函数。
  • std::hash(your_std_string)? :P♥C++11

标签: c++ string hash type-conversion


【解决方案1】:

C++11 在标头<functional> 中引入了一个实现定义的散列函数std::hash,它专门用于字符串类std::stringstd::wstring 等。

就这么简单:

#include <iostream>
#include <functional> //for std::hash
#include <string>

int main() {
    std::string str = "Hello World";
    std::hash<std::string> hasher;
    auto hashed = hasher(str); //returns std::size_t
    std::cout << hashed << '\n'; //outputs 2146989006636459346 on my machine
}

为您的用户定义类型专门化std::hash 也不是很复杂。但请注意,const char* 或任何 C 字符串没有 std::hash 特化。

【讨论】:

    【解决方案2】:

    您需要一个 散列函数 将您的字符串转换为或多或少的任意整数。有很多可供选择,是的,它们通常使用字符串的 ASCII 值。这是一个叫 djb2

    unsigned long hash(const std::string& str)
    {
        unsigned long hash = 5381;
        for (size_t i = 0; i < str.size(); ++i)
            hash = 33 * hash + (unsigned char)str[i];
        return hash;
    }
    

    请不要认为这是一个好的散列函数,这是一个完全不同的话题。

    【讨论】:

    • 如果我要转换的字符串是州名,比如“阿拉斯加”或“伊利诺伊州”,我可以这样做吗?
    • @user2109706 是的,这个函数会将 any 字符串转换为哈希码。重要的一点是“阿拉斯加”和“伊利诺伊”将被转换成不同的哈希码(我希望)。
    • 啊,我明白了。谢谢约翰,我会试试看的。
    【解决方案3】:

    here开始,有两个函数可以将字符串转换为uint32_tuint64_t,转换为uint32_t

    inline uint32_t hash_str_uint32(const std::string& str) {
    
        uint32_t hash = 0x811c9dc5;
        uint32_t prime = 0x1000193;
    
        for(int i = 0; i < str.size(); ++i) {
            uint8_t value = str[i];
            hash = hash ^ value;
            hash *= prime;
        }
    
        return hash;
    
    }
    

    测试:

    【讨论】:

      【解决方案4】:

      boost::lexical_cast 可能适合您的需要。

      #include <string>
      #include <boost/lexical_cast.hpp>
      
      int main()
      {
          std::string str = "123456";
          try
          {
             int i = boost::lexical_cast<int>(str);
             // i should be 123456 here
          }
          catch(const boost::bad_lexical_cast&)
          {
              //bad format
          }
      }
      

      【讨论】:

      • 我不认为 OP 是在询问一串数字到一个整数。
      • 是的,我需要将诸如“阿拉斯加”或“伊利诺伊州”之类的单词转换为 int,这样我才能对其进行哈希处理。
      • @user2109706:将(非数字)字符串转换为 int 的过程就是散列它。
      【解决方案5】:

      如果字符串会留在内存中,一些库只是将字符串的地址作为哈希返回。

      【讨论】:

        猜你喜欢
        • 2020-07-14
        • 2016-10-05
        • 2012-04-06
        • 2011-04-22
        • 2013-05-07
        • 2017-08-20
        • 2021-09-05
        • 2018-12-30
        • 2011-04-21
        相关资源
        最近更新 更多