1

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

真的一样

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

关于唯一性?

Word是类型String

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

4

2 回答 2

2

很明显,实现中的任何冲突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);

该程序将哈希码值 映射i7 * i模 2 16,并验证该范围内的每个数字是否只生成一次。

Count of duplicate mappings found: 0

演示。

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

哪一个更好?

没有区别。

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

于 2016-09-29T16:54:51.803 回答
0

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

于 2016-09-29T16:59:14.770 回答