bar*_*art 5 .net c# dictionary bitarray gethashcode
我需要在GetHashCode中为BitArray生成快速哈希码.我有一个字典,其中键是BitArrays,所有BitArrays长度相同.
有没有人知道从可变位数生成良好哈希的快速方法,如在这种情况下?
更新:
我最初采用的方法是直接通过反射访问内部int数组(速度比这种情况下的封装更重要),然后对这些值进行异或.XOR方法似乎运行良好,即在"字典"中搜索时,我的"等于"方法不会过度调用:
public int GetHashCode(BitArray array)
{
int hash = 0;
foreach (int value in array.GetInternalValues())
{
hash ^= value;
}
return hash;
}
Run Code Online (Sandbox Code Playgroud)
但是,Mark Byers建议并在StackOverflow其他地方看到的方法稍好一些(对于我的测试数据,XOR为16570等于呼叫,而对于XOR为16608).请注意,此方法修复了前一个错误,其中超出位数组末尾的位可能会影响散列值.如果位数组的长度减少,则可能发生这种情况.
public int GetHashCode(BitArray array)
{
UInt32 hash = 17;
int bitsRemaining = array.Length;
foreach (int value in array.GetInternalValues())
{
UInt32 cleanValue = (UInt32)value;
if (bitsRemaining < 32)
{
//clear any bits that are beyond the end of the array
int bitsToWipe = 32 - bitsRemaining;
cleanValue <<= bitsToWipe;
cleanValue >>= bitsToWipe;
}
hash = hash * 23 + cleanValue;
bitsRemaining -= 32;
}
return (int)hash;
}
Run Code Online (Sandbox Code Playgroud)
GetInternalValues扩展方法实现如下:
public static class BitArrayExtensions
{
static FieldInfo _internalArrayGetter = GetInternalArrayGetter();
static FieldInfo GetInternalArrayGetter()
{
return typeof(BitArray).GetField("m_array", BindingFlags.NonPublic | BindingFlags.Instance);
}
static int[] GetInternalArray(BitArray array)
{
return (int[])_internalArrayGetter.GetValue(array);
}
public static IEnumerable<int> GetInternalValues(this BitArray array)
{
return GetInternalArray(array);
}
... more extension methods
}
Run Code Online (Sandbox Code Playgroud)
欢迎任何改进建议!
如果位数组为 32 位或更短,则只需将它们转换为 32 位整数(如有必要,用零位填充)。
如果它们可以更长,那么您可以将它们转换为一系列 32 位整数并对它们进行异或,或者更好:使用有效 Java 中描述的算法。
public int GetHashCode()
{
int hash = 17;
hash = hash * 23 + field1.GetHashCode();
hash = hash * 23 + field2.GetHashCode();
hash = hash * 23 + field3.GetHashCode();
return hash;
}
Run Code Online (Sandbox Code Playgroud)
取自这里。field1、field2分别对应前32位、后32位等。
| 归档时间: |
|
| 查看次数: |
2478 次 |
| 最近记录: |