C# DateRange类的好哈希代码是什么

C# DateRange类的好哈希代码是什么,c#,data-structures,dictionary,gethashcode,C#,Data Structures,Dictionary,Gethashcode,我有以下课程 public class DateRange { private DateTime startDate; private DateTime endDate; public override bool Equals(object obj) { DateRange other = (DateRange)obj; if (startDate != other.startDate) return fal

我有以下课程

public class DateRange
{
    private DateTime startDate;
    private DateTime endDate;
    public override bool Equals(object obj)
    {
        DateRange other = (DateRange)obj;
        if (startDate != other.startDate)
            return false;
        if (endDate != other.endDate)
            return false;
        return true;
    }
    ...
}
我需要将一些值存储在键入日期范围的字典中,如:

Dictionary<DateRange, double> tddList;
字典tddList;
如何重写
DateRange
类的
GetHashCode()
方法

return startDate.GetHashCode() ^ endDate.GetHashCode();
也许是个好的开始。当开始日期和结束日期之间的距离相等,但日期不同时,您必须检查是否得到了良好的分布


也许是个好的开始。当startDate和endDate之间的距离相等,但日期不同时,您必须检查是否得到了良好的分布。

我使用有效Java的这种方法来组合哈希:

unchecked
{
    int hash = 17;
    hash = hash * 31 + field1.GetHashCode();
    hash = hash * 31 + field2.GetHashCode();
    ...
    return hash;
}

在这种情况下,没有理由不起作用。

我使用有效Java的这种方法来组合哈希:

unchecked
{
    int hash = 17;
    hash = hash * 31 + field1.GetHashCode();
    hash = hash * 31 + field2.GetHashCode();
    ...
    return hash;
}

在这种情况下,没有理由不起作用。

您必须移动范围的一端,否则两个相等的日期将散列为零,我认为这是一种非常常见的情况:

return startDate.GetHashCode() ^ (endDate.GetHashCode() << 4);

返回startDate.GetHashCode()^(endDate.GetHashCode()您必须移动范围的一端,否则两个相等的日期将散列为零,我认为这是一种非常常见的情况:

return startDate.GetHashCode() ^ (endDate.GetHashCode() << 4);

<代码>返回开始日期。GTHASCODE()^(EnDealth.GethasoCudie)(P>),考虑好散列函数应该具有什么特性。它必须:

  • 与Equals一致-也就是说,如果两个对象的Equals为真,那么两个哈希代码也必须相同
  • 永不崩溃
它应该:

  • 快点
  • 对相似的输入给出不同的结果
我要做的是想出一个非常简单的算法;比如,从第一个哈希代码中提取16位,从第二个哈希代码中提取16位,并将它们组合在一起。让自己做一个代表性样本的测试用例;实际使用的日期范围,看看这个算法是否提供了良好的分布


一个常见的选择是将两个哈希值异或在一起。对于这种类型,这不一定是一个好主意,因为似乎有人希望表示从X到X的零长度范围。如果对两个相等日期时间的哈希值进行异或,则总是得到零,这似乎是导致大量哈希冲突的原因。

嗯,考虑到呃一个好的散列函数应该具有什么特征。它必须:

  • 与Equals一致-也就是说,如果两个对象的Equals为真,那么两个哈希代码也必须相同
  • 永不崩溃
它应该:

  • 快点
  • 对相似的输入给出不同的结果
我要做的是想出一个非常简单的算法;比如,从第一个哈希代码中提取16位,从第二个哈希代码中提取16位,并将它们组合在一起。让自己做一个代表性样本的测试用例;实际使用的日期范围,看看这个算法是否提供了良好的分布


一个常见的选择是将两个哈希值异或在一起。对于这种类型,这不一定是一个好主意,因为似乎有人希望表示从X到X的零长度范围。如果对两个相等日期时间的哈希值进行异或,则总是得到零,这似乎是导致大量哈希冲突的原因。

这取决于n我希望看到它与一起使用的值

如果它通常有不同的日值,而不是同一天的不同时间,并且它们在一个世纪之内,我会使用:

unchecked
{
    int hash = startDate.Year + endDate.Year - 4007;
    hash *= 367 + startDate.DayOfYear;
    return hash * 367 + endDate.DayOfYear;
}
这可以很好地将位分配到期望值,同时减少移位过程中丢失的位数(特别是当散列被输入到使用同一素数的模来避免冲突的东西中时,当产生更小的散列来分布在它的桶中时)我选择了素数高于更明显的选择,因为它们仅仅在上面,所以仍然相当“紧”对于位分布。我不太担心两次使用同一个素数,因为它们在这种方式下非常“紧”,但如果你有一个包含367个桶的基于哈希的集合,这会造成伤害。这可以很好地处理(但不太好)过去或未来的日期,但如果假设在同一天内几乎没有范围,那就太可怕了(时间不同)是错误的,因为信息完全丢失了

如果我期望(或为其他方的普遍使用而写作,但无法假设其他情况),我会选择:

int startHash = startDate.GetHashCode();
return (((startHash >> 24) & 0x000000FF) | ((startHash >> 8) & 0x0000FF00) | ((startHash << 8) & 0x00FF0000) | (unchecked((int)((startHash << 24) & 0xFF000000)))) ^ endDate.GetHashCode();
int startHash=startDate.GetHashCode();

return((startHash>>24)和0x000000FF)|((startHash>>8)和0x0000FF00)|((startHash它取决于我希望看到它与一起使用的值

如果它通常有不同的日值,而不是同一天的不同时间,并且它们在一个世纪之内,我会使用:

unchecked
{
    int hash = startDate.Year + endDate.Year - 4007;
    hash *= 367 + startDate.DayOfYear;
    return hash * 367 + endDate.DayOfYear;
}
这可以很好地将位分配到期望值,同时减少移位过程中丢失的位数(特别是当散列被输入到使用同一素数的模来避免冲突的东西中时,当产生更小的散列来分布在它的桶中时)我选择了素数高于更明显的选择,因为它们仅仅在上面,所以仍然相当“紧”对于位分布。我不太担心两次使用同一个素数,因为它们在这种方式下非常“紧”,但如果你有一个包含367个桶的基于哈希的集合,这会造成伤害。这可以很好地处理(但不太好)过去或未来的日期,但如果假设在同一天内几乎没有范围,那就太可怕了(时间不同)是错误的,因为信息完全丢失了

如果我期望(或为其他方的普遍使用而写作,但无法假设其他情况),我会选择:

int startHash = startDate.GetHashCode();
return (((startHash >> 24) & 0x000000FF) | ((startHash >> 8) & 0x0000FF00) | ((startHash << 8) & 0x00FF0000) | (unchecked((int)((startHash << 24) & 0xFF000000)))) ^ endDate.GetHashCode();