C++ Can-std::hash<;标准::字符串>;是否为不同的字符串返回相同的值?

C++ Can-std::hash<;标准::字符串>;是否为不同的字符串返回相同的值?,c++,c++11,c++17,C++,C++11,C++17,下面的链接提到了碰撞的可能性,但我试图使用它查找重复条目: 我正在使用std::hash并将返回值存储在std::unordered_集合中。如果emplace失败,我将标记字符串,因为它是重复字符串。是,std::hash为不同的std::string返回相同的结果。 不同的编译器创建的bucket是不同的 在链接中找到基于编译器的实现: 哈希通常是从大的值空间到小的值空间的函数,例如从所有字符串空间到64位整数。字符串比64位整数多得多,因此显然多个字符串可以具有相同的哈希。好的散列函数是

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


我正在使用
std::hash
并将返回值存储在std::unordered_集合中。如果emplace失败,我将标记字符串,因为它是重复字符串。

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

在链接中找到基于编译器的实现:

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

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

  • 查找具有相同哈希值的字符串(即找到字符串的“哈希桶”)
  • 将您的字符串与具有相同哈希值的其他字符串逐个进行比较
  • std::unordered_set
    可以做到这一点,更不用说细节了。请注意,这是为您而做的,因此您需要对自己进行散列,然后将结果存储在
    std::unordered\u集合中


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

    是的,两个不同的字符串可能共享相同的哈希。简单地说,让我们假设您有一个存储在8位类型(
    无符号字符
    )中的哈希。 也就是说,2^8=256个可能的值。这意味着您只能有256个唯一的任意输入哈希。
    由于您可以创建超过256个不同的字符串,因此哈希不可能对所有可能的字符串都是唯一的

    std::size\t
    是64位类型,因此如果将其用作散列值的存储,则可能会有2^64个散列,这略多于256个可能的唯一散列,但仍然不足以区分可以创建的所有可能字符串


    您不能仅用64位存储整本书。

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

    存在一个名为“”的东西,它生成一个将返回唯一结果的哈希函数。然而,这仅对一组已知的输入有保证。来自外部的未知输入可能会产生匹配的哈希数。这种可能性可以通过使用


    然而,在某些情况下,使用所有这些散列计算,程序最好在未排序的线性数组中进行简单的字符串比较。如果C大得离谱,谁会在乎手术是否是
    O(1)+C

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