2010-06-13 72 views
0

我不好意思問這個問題,但我目前無法編程和測試,因爲我在手機上寫這個,而不是在我的開發機器上:P (如果有人回答,簡單的代表點!XD)數組/列表和計算哈希值(VB,C#)

無論如何,我已經有了使用String對象的hash值的經驗。例如,如果我的StringA和StringB都等於「foo」,它們都會計算出相同的散列值,因爲它們被設置爲相等的值。

現在如果我有一個List,T是一個本地數據類型。如果我試圖計算ListA和ListB的哈希值,假設它們都是相同的大小幷包含相同的信息,那麼它們是否也具有相同的哈希值?

假設以具有5 {5,2,0,1,3}的長度

+0

你是什麼意思「計算ListA和ListB的哈希值」?你是否認爲列表中每個項目的散列值是相同的 - 如果是,那麼是的。否則我不認爲它們會一樣。 – VoodooChild 2010-06-13 01:45:40

+0

例如,ListA.Hashvalue = ListB.Hashvalue?不知道.Net是否會這樣做, – 2010-06-13 01:48:04

回答

0

如果你談論的是內置列表類型,那麼不是,它們將不相等。爲什麼?因爲List<T>是一個引用類型,所以相等將會比較引用是否相同。如果您正在創建自定義列表類型,那麼您可以覆蓋EqualsGetHashCode方法來支持此行爲,但它不會在內置類型中發生。

2

這取決於如何計算散列值,以及如何定義平等「字節」的樣本數據集。例如,根據您的應用程序,恰好包含相同值的數組的兩個不同實例可能不會被視爲相同。在這種情況下,您可以將每個數組的地址或其他唯一值作爲哈希函數的一部分。

但是,如果要考慮包含相同值的不同數組,則只需使用數組中的值計算列表哈希。當然,那麼你必須考慮在確定平等(並因此影響你的哈希函數)時,是否排序對你有用。

+0

是的,順序是重要的。沒有想到,但是是的,這將是至關重要的 – 2010-06-13 01:47:42

+0

+1,關於平等:你可以重載平等運算符,不是嗎? – VoodooChild 2010-06-13 01:49:22

1

如果項目的順序很重要,那麼你可以像這樣產生一個序列哈希碼。

public static int GetOrderedHashCode<T>(this IEnumerable<T> source) 
{ 
    unchecked 
    { 
     int hash = 269; 
     foreach (T item in source) 
     { 
      hash = (hash * 17) + item.GetHashCode; 
     } 
     return hash; 
    } 
} 

如果項目的順序並不重要,那麼你可以做這樣的事情,而不是:

public static int GetUnorderedHashCode<T>(this IEnumerable<T> source) 
{ 
    unchecked 
    { 
     int sum = 907; 
     int count = 953; 
     foreach (T item in source) 
     { 
      sum = sum + item.GetHashCode(); 
      count++ 
     } 
     return 991 * sum * count; 
    } 
} 

(請注意,這兩種方法都會有較大的集合表現不佳,其中你可能想要實現某種緩存,只在收集變化時重新計算哈希碼。)