2010-08-16 64 views
1

只是想知道:如果我有兩個SortedDictionary對象,找出它們的內容是否相同的最快方法是什麼? 循環所有的鍵和檢查值聽起來不像是最好的解決方案。 只需檢查GetHashCode()就足夠了嗎?SortedDictionary <TKey,TValue>:檢查內容是否等於另一個SortedDictionary?

編輯:我試了一下。看到這個代碼:

SortedDictionary<string, string> o1 = new SortedDictionary<string, string>(); 
SortedDictionary<string, string> o2 = new SortedDictionary<string, string>(); 
o1["k1"] = "v1"; 
o1["k2"] = "v2"; 
o1["k3"] = "v3"; 

o2["k2"] = "v2"; 
o2["k1"] = "v1"; 
o2["k3"] = "v3"; 

Console.WriteLine("o1:"); 
foreach (KeyValuePair<string, string> oKeyValuePair in o1) 
{ 
    Console.WriteLine(oKeyValuePair.GetHashCode()); 
} 
Console.WriteLine("o2:"); 
foreach (KeyValuePair<string, string> oKeyValuePair in o2) 
{ 
    Console.WriteLine(oKeyValuePair.GetHashCode()); 
} 
Console.ReadKey(); 

爲個人鍵值對的散列碼是兩種排序字典一樣的,即使添加值的順序不同。這很好。 所以我錯過了一個步驟:我如何從所有的哈希碼獲得一個唯一的哈希碼?

回答

2

您必須準備好循環瀏覽所有內容,但首先您可以測試一些重要的捷徑。

第一個捷徑是檢查對象身份。雖然「A是A」並不像Ayn Rand似乎認爲的那麼深刻,但它是使等號代碼更快的便捷方式。身份始終需要平等,並且在實際代碼中最終會將某些事情與自身進行比較(尤其是集合查找,循環以及某個對象通過幾層代碼時)。

另一個是,如果內容相同,大小不能不同,並且大小很快就可以獲得。

因此你可以得到最快的是:

public static bool EqualSortedDict<K, V>(SortedDictionary<K, V> x, SortedDictionary<K, V> y) 
{ 
    if(ReferenceEquals(x, y)) 
    return true; 
    if(ReferenceEquals(x, null) || ReferenceEquals(y, null)) 
    return false; //both being null already hit above. 
    if(x.Count != y.Count) 
    return false; 
    if(!x.Comparer.Equals(y.Comparer)) 
    return false;//check if this is what you need. Probably is but might 
       //not be in some cases. 
    foreach(KeyValuePair<K, V> kvp in x) 
    { 
    V cmpValue = default(V); 
    if(!y.TryGetValue(kvp.Key, out cmpValue) || !kvp.Value.Equals(cmpValue)) 
     return false; 
    } 
    return true; 
} 

注意,原因GetHashCode()方法沒有上述工作是GetHashCode的對SortedDictionary的默認實現()只適用於對象的身份。如果你需要一個基於值的GetHashCode()(如果你的SortedDictionary本身就是一個鍵或放置在HashSet中),那麼你將不得不實現一個IEqualityComparer來產生一個合適的哈希碼。即使這樣,它可能需要很長時間來計算自己(它可能總是遍歷所有項目來做你想做的),而a.GetHashCode()!= b.GetHashCode()證明a!= b(對於由hashcode支持的相等定義),a.GetHashCode()== b.GetHashCode()不證明a == b,因爲會有衝突。

+0

聽起來很合理,我最終使用了類似的實現。原來,關鍵值對的哈希值可能會改變。謝謝。 – Krumelur 2010-08-18 08:53:35

+0

@Krumelur。實際上,現在看看這個,因爲kvp命令是按排序字典排序的,所以在每個MoveNext之後抓取兩個枚舉器並比較Current會更快。只要你不想考慮使用不同比較器的字典(在這種情況下,排序順序會不同,這種加速將不起作用),這會將第二個字典中相關值的每次搜索減少到O( 1)。我在更廣泛地思考(以上是基於散列的字典或其他不保留排序順序的唯一方法)。 – 2010-08-18 09:26:42

3

沒有,檢查GetHashCode是不夠的,即使SortedDictionary<,>推翻它 - 我不相信它。

據我所知,你必須循環檢查所有的鍵和值。從根本上講,這就是任何解決方案必須做的。你也應該檢查所涉及的比較函數是否也是一樣的,否則這些字典並不是真的相同。

+0

+1一比一比 – 2010-08-16 11:32:14