2014-03-03 44 views
3

我有一個函數,只是打算出一個易於理解的時尚頻繁項目集的字典。目標是首先按字典鍵的大小排序,然後按照數字列表的字典順序排序。 ThenBy聲明中出現問題,因爲註釋「hello」將被無限期打印。如果我改變ThenBy不使用比較器,並簡單地使用另一個int或字符串值,它可以正常工作,所以我顯然做錯了。Linq然後無限期運行

public static void printItemSets(Dictionary<List<int>, int> freqItemSet) 
{ 
    List<KeyValuePair<List<int>, int>> printList = freqItemSet.ToList(); 
    printList = printList.OrderBy(x => x.Key.Count) 
         .ThenBy(x => x.Key, new ListComparer()) 
         .ToList(); 
} 

用於ListComparer的代碼如下:

public class ListComparer: IEqualityComparer<List<int>>, IComparer<List<int>> 
{ 
    public int Compare(List<int> a, List<int> b) 
    { 
     int larger = a.Count > b.Count ? 1: -1; 
     for (int i = 0; i < a.Count && i < b.Count; i++) 
     { 
      if (a[i] < b[i]) 
      { 
       return -1; 
      } 
      else if (a[i] > b[i]) 
      { 
       return 1; 
      } 
      else { } 
     } 
     return larger; 
    } 
} 

非常簡單的測試情況:

int[] a = {1, 3, 5}; 
int[] b = { 2, 3, 5 }; 
int[] c = { 1, 2, 3, 5 }; 
int[] d = { 2, 5 }; 
int[] e = { 1, 3, 4 }; 
List<int> aL = a.ToList<int>(); 
List<int> bL = b.ToList<int>(); 
List<int> cL = c.ToList<int>(); 
List<int> dL = d.ToList<int>(); 
List<int> eL = e.ToList<int>(); 
Dictionary<List<int>, int> test = new Dictionary<List<int>, int>(new ListComparer()); 
test.Add(aL, 1); 
test.Add(bL, 1); 
test.Add(cL, 1); 
test.Add(dL, 1); 
test.Add(eL, 1); 
+2

看起來它應該終止。不過,它似乎有可能會特別慢。你是否嘗試過將這個作爲單元測試運行?你有沒有嘗試過使用只有少數元素的模擬字典來確保代碼能夠按照預期工作? – Yuck

+0

我目前正在用僅包含4個項目的字典對其進行測試,所以應該足夠小。由於它只是一個打印功能,我不期待特大的列表,它可能還是可以的。我主要處於「草稿」模式,我只是想寫一些能正常工作的東西。 –

+1

您的比較器不處理相同的項目。如果項目相同,則這兩個項目的順序決定哪個項目被視爲「較大」。比較器因此不是「反身」的。這是屬性排序算法所依賴的。第一行應該是'varlarge = a.Count.CompareTo(b.Count);'而不是。也就是說,這不會導致你看到的問題。 – Servy

回答

2

問題是ListComparer如果陣列是相同的不檢查。對於xy這兩個相同的陣列都被傳入兩次。檢查xy是否相等可以解決您的問題。

1

您的比較器不處理相同的項目。如果項目相同,則這兩個項目的順序決定哪個項目被視爲「較大」。比較器因此不是「反身」的。反身性是屬性排序算法所依賴的。

的第一行應該是var larger = a.Count.CompareTo(b.Count);代替,從而使真正的平等名單將返回0,而不是要麼-11