【问题标题】:C# GetHashCode ImplementationC# GetHashCode 实现
【发布时间】:2017-02-08 02:10:56
【问题描述】:

public override int GetHashCode()
{
    return Word.GetHashCode();
}

真的一样

public override int GetHashCode()
{
    return (int) Word.GetHashCode() * 7;
}

关于唯一性?

Word 的类型为 String

编辑:我忘了说,在程序中实现哪个更好,选项 1 或 2?

【问题讨论】:

  • 由于哈希码既不是必需的也不是唯一的,因此您的问题的答案是“是”,因为这两种实现都会产生非唯一的哈希码。
  • Word.GetHashCode() 的任何碰撞在乘以 7 后仍然会发生碰撞。而且演员表也毫无意义。
  • 扩展 juharr 的评论,如果 World.GetHashCode() 为 worldA 和 worldB 生成 6,那么 World.GetHashCode() * 7 为 worldA 和 worldB 生成 42...
  • 你到底是什么意思?如果您在第一个单词中获得两个不同的唯一结果,您将从第二个单词中获得两个不同的唯一结果。同样,如果您从第一个单词中的两个单词中得到两个相同的结果,那么第二个单词也会产生两个相同的结果。从查看代码来看,这似乎有些明显,所以感觉您的问题比我认为可以通过详细说明来解决的问题更多。
  • (3 * 7) == (3 * 7) 真的和3 == 3 一样吗?

标签: c# gethashcode hash-code-uniqueness


【解决方案1】:

很明显,Word.GetHashCode() 实现中的任何冲突都会导致(int) Word.GetHashCode() * 7 实现中的冲突,因为相同的数字相乘会产生相同的结果。

一个更有趣的问题是,第一个实现中的非冲突哈希码是否会导致第二个实现中的冲突。事实证明,答案是否定的,因为int7 的范围是互质数。因此,乘法在丢弃溢出后会产生唯一的映射。

您可以使用两个字节的哈希码运行一个小测试,看看会发生什么:

const int Max = 1<<16;
var count = new int[Max];
for (int i = 0 ; i != Max ; i++) {
    count[(i * 7) & (Max-1)]++;
}
var notOne = 0;
for (int i = 0 ; i != Max ; i++) {
    if (count[i] != 1) {
        notOne++;
    }
}
Console.WriteLine("Count of duplicate mappings found: {0}", notOne);

该程序将i(哈希码值)映射到7 * i 模216,并验证该范围内的每个数字是否只产生一次。

Count of duplicate mappings found: 0

Demo.

如果将7 替换为偶数,结果将大不相同。现在,来自原始集合的多个哈希码将映射到目标集合中的单个哈希码。如果您记得乘以偶数总是使最低有效位为零,您可以直观地理解这一点。因此,一些信息会丢失,具体取决于偶数可以被二除多少次。

哪个更好?

没有区别。

注意:以上假设您忽略整数溢出。

【讨论】:

  • 是的,我忘了说 pime 号码是故意的。那么选项 A 或 B 哪个更好?
  • 因为这确定没有区别,所以使用更简单的选项。
  • @HendrikBreezy 由于 .NET 谨慎使用主要存储桶计数,因此没有区别。
【解决方案2】:

由于您没有在unchecked 上下文中运行代码,因此后者将在任何时候发生溢出时抛出异常,这很有可能(6/7 的哈希范围会抛出,因此通常均匀分布式哈希码有大约 6/7 的机会抛出异常)。

【讨论】:

  • msdn.microsoft.com/en-gb/library/a569z7k8.aspx 它说“包含非常量项的表达式在编译时和运行时默认情况下是未检查的”,所以这是否意味着如果不明确检查它就不会被检查?我承认我并没有真正玩过任何我需要担心检查/未检查的事情,所以我很容易出错......
  • @Chris C# 编译器和 VS 默认为未选中。
猜你喜欢
  • 1970-01-01
  • 2011-02-22
  • 2012-01-26
  • 2011-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-22
  • 1970-01-01
相关资源
最近更新 更多