Tôi cần tạo mã băm nhanh trong GetHashCode cho một BitArray. Tôi có một từ điển mà các khóa là BitArrays, và tất cả các BitArrays có cùng độ dài.Tạo mã băm tốt (GetHashCode) cho một BitArray
Có ai biết cách nhanh chóng để tạo ra băm tốt từ số bit thay đổi, như trong trường hợp này không?
UPDATE:
Cách tiếp cận ban đầu tôi mất đã để truy cập mảng nội ints trực tiếp thông qua phản xạ (tốc độ là quan trọng hơn cả đóng gói trong trường hợp này), sau đó XOR những giá trị đó. Cách tiếp cận XOR dường như làm việc tốt tức là của tôi 'Equals' phương pháp không được gọi là quá mức khi tìm kiếm trong từ điển:
public int GetHashCode(BitArray array)
{
int hash = 0;
foreach (int value in array.GetInternalValues())
{
hash ^= value;
}
return hash;
}
Tuy nhiên, cách tiếp cận đề nghị Mark Byers và nhìn thấy ở đâu đó trên StackOverflow là tốt hơn một chút (16.570 Equals cuộc gọi so với 16608 cho XOR cho dữ liệu thử nghiệm của tôi). Lưu ý rằng cách tiếp cận này sửa lỗi trong phần trước, trong đó bit ngoài phần cuối của mảng bit có thể ảnh hưởng đến giá trị băm. Điều này có thể xảy ra nếu mảng bit bị giảm độ dài.
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;
}
Các GetInternalValues phương pháp khuyến nông được thực hiện như thế này:
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
}
Bất kỳ đề xuất cải tiến được hoan nghênh!
Tôi đã thấy cách tiếp cận của bạn được đề cập ở đâu đó, nhưng tôi không thực sự hiểu lý thuyết đằng sau nó hoặc lựa chọn các số nguyên tố 'ma thuật'. Cách tiếp cận này có hiệu quả hơn một chút so với cách tiếp cận XOR ban đầu tôi đã thực hiện (16570 Equals calls so với 16608 cho XOR cho dữ liệu thử nghiệm của tôi). Xem chỉnh sửa của tôi để biết thêm chi tiết. – bart