【问题标题】:Can std::hash<std::string> return the same value for different strings?std::hash<std::string> 可以为不同的字符串返回相同的值吗?
【发布时间】:2019-12-08 06:15:47
【问题描述】:

下面的链接提到了碰撞的可能性,但我正在尝试使用它来查找重复条目:

http://www.cplusplus.com/reference/functional/hash/

我正在使用std::hash&lt;std::string&gt; 并将返回值存储在 std::unordered_set 中。如果 emplace 失败,我将字符串标记为重复字符串。

【问题讨论】:

  • 视情况而定。你想做什么?
  • 我想为多个字符串生成哈希值。如果哈希函数返回相同的值,我将其标记为找到重复的字符串。
  • 您正在获取任意数量的字符(字节),其长度可能为数百位,并将其减少为 32 位或 64 位整数。是的,对于不同的字符串,会有重复的哈希值。您可以先检查哈希;如果匹配,则比较字符串。
  • C++ 版本不能改变你不能拥有无限不同的有限长度哈希的事实。这是数学。​​
  • ...您还可以期望这些测试运行很长时间。

标签: c++ c++11 c++17


【解决方案1】:

哈希通常是从大空间值到小空间值的函数,例如从所有字符串的空间到 64 位整数。字符串比 64 位整数多 很多,因此显然多个字符串可以具有相同的哈希值。一个好的散列函数是没有简单的规则来关联具有相同散列值的字符串。

所以,当我们想要使用哈希来查找重复的字符串(或重复任何内容)时,它始终是一个两阶段的过程(至少):

  1. 查找具有相同哈希的字符串(即为您的字符串找到“哈希桶”)
  2. 将您的字符串与具有相同哈希的其他字符串逐个字符进行比较。

std::unordered_set 就是这样做的——别管细节了。请注意,它为您执行此操作,因此您不必自己散列,然后将结果存储在 std::unordered_set 中。

最后,请注意,还有其他功能可以用于初始重复筛选 - 或用于在相同哈希值中进行搜索。例如,字符串长度:在逐个字符比较两个字符串之前,检查它们的长度(您应该能够在不实际迭代字符串的情况下访问它们);不同的长度 -> 不相等的字符串。

【讨论】:

    【解决方案2】:

    是的,两个不同的字符串可能会共享同一个哈希值。简单地说,假设您有一个以 8 位类型 (unsigned char) 存储的哈希。 那是 2^8 = 256 个可能的值。这意味着您只能拥有任意输入的 256 个唯一哈希值。
    由于您绝对可以创建超过 256 个不同的字符串,因此哈希不可能对所有可能的字符串都是唯一的。

    std::size_t 是 64 位类型,因此如果您将其用作哈希值的存储,您将拥有 2^64 个可能的哈希值,略多于 256 个可能的唯一哈希值,但仍然不足以区分您可以创建的所有可能的字符串。

    你不能只用 64 位存储整本书。

    【讨论】:

      【解决方案3】:

      是的,它可以为不同的字符串返回相同的结果。这是将无限范围的可能性减少到单个 64 位数字的自然结果。

      存在称为“perfect hash functions”的东西,它会产生一个哈希函数,该函数将返回唯一的结果。但是,这仅对一组已知的输入有保证。来自外部的未知输入可能会产生匹配的哈希数。使用bloom filter 可以减少这种可能性。

      然而,在某些时候,通过所有这些哈希计算,程序在未排序的线性数组中进行简单的字符串比较会更好。如果 C 大得离谱,谁在乎操作是 O(1)+C

      【讨论】:

        【解决方案4】:

        是的,std::hash 为不同的std::string 返回相同的结果。 不同的编译器对桶的创建是不同的。

        在链接中找到基于编译器的实现: hashing and rehashing for std::unordered_set

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-03-21
          • 2022-10-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-18
          相关资源
          最近更新 更多