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();