2017-05-02 59 views
1

我實現了一個使用字典與元組鍵的算法,算法的工作原理,但它非常慢。我有一組字符串。我試圖實現一個關聯矩陣,其中A["abc","bcde"] = 2,這兩個字符串的重疊量。 L中的元組是A中的鍵。L是一個排序後的數組=> A [L [i]] < A [L [i + 1]] 我合併了集合中具有最大重疊的兩個字符串, 「矩陣」和L列表。我在一個循環中進行,直到該集合只有1個元素。我的問題是,用字典算法太慢。有沒有更有效的方法來做到這一點?這裏是我的代碼:C#中的關聯矩陣是否有更有效的方法?

List<string> words = new List<string>(wordsFromFile); 

Dictionary<Tuple<string, string>, int> A = new Dictionary<Tuple<string, string>, int>(); 
List<Tuple<string, string>> L = new List<Tuple<string,string>>(); 

(我用的計數的排序作出L.之後刷新矩陣和列表是非常耗費時間:)

  while (words.Count > 1) 
      { 
       string LastItem1 = L.Last().Item1; 
       string LastItem2 = L.Last().Item2; 
       words.Remove(LastItem1); 
       words.Remove(LastItem2); 
       string newElement = merge(LastItem1, LastItem2); 
       words.Add(newElement); 
       for (int i = 0; i < words.Count; ++i) 
       { 
        if (words[i] == newElement) 
        { 
         Tuple<string, string> tmp = new Tuple<string, string>(newElement, newElement); 
         A[tmp] = 0; 
        } 
        else 
        { 
         Tuple<string, string> tmp = new Tuple<string, string>(newElement, words[i]); 
         A[tmp] = A[new Tuple<string, string>(LastItem2, words[i])]; 
         tmp = new Tuple<string, string>(words[i], newElement); 
         A[tmp] = A[new Tuple<string, string>(words[i], LastItem1)]; 
        } 
       } 
       var itemsToRemove = A.Where(f => f.Key.Item1 == LastItem1 || f.Key.Item1 == LastItem2 || f.Key.Item2 == LastItem1 || f.Key.Item2 == LastItem2).ToArray(); 
       foreach (var item in itemsToRemove) 
        A.Remove(item.Key); 

       L.Remove(L.Last()); 
       for (int i = 0; i < L.Count(); ++i) 
       { 
        if (L[i].Item1 == LastItem2 && L[i].Item2 != LastItem1 && L[i].Item2 != newElement && L[i].Item2 != LastItem2) L[i] = new Tuple<string, string>(newElement, L[i].Item2); 
        else if (L[i].Item2 == LastItem1 && L[i].Item1 != LastItem1 && L[i].Item1 != newElement && L[i].Item1 != LastItem2) L[i] = new Tuple<string, string>(L[i].Item1, newElement); 
       } 

       var listitemsToRemove = L.Where(f => f.Item1 == LastItem1 || f.Item2 == LastItem2 || f.Item1 == LastItem2 || f.Item2 == LastItem1).ToArray(); 
       foreach (var item in listitemsToRemove) L.Remove(item); 
       listitemsToRemove = L.Where(f => f.Item2 == LastItem2).ToArray(); 

      } 
+0

詞典是驚人的快,不會是你的問題。 – Dessus

+0

你真的應該發佈[mcve]。 – Enigmativity

回答

0
  1. 它很難讀高混淆代碼,但是有一兩件事,在跳出我是這樣的:

    L [我] .Item1

    哪個是副O2與字典相比最佳。我想你可能想要保留排序,在這種情況下,你可以使用OrderedDictionary <>

  2. 你可以使用for循環,它可以通過你的情況下的foreach循環進行優化。確實,for循環在原始性能方面更快,但不會影響您使用它的方式。你做了大約12個查找L這是一個列表。它不是一個數組,它是一個列表,所以在這樣的列表中選擇項目會隨着時間的推移而失去速度。 Foreach針對這種特定情況進行了優化,並且如果迭代列表(除非在引用循環更快的情況下引入了int計數器),則可以更快速地實現。

  3. 字[I]做3個查找(低效相比,foreach循環),它看起來它一旦

+1

'List'基本上是一個數組,也許你把它和'LinkedList'混淆了?特別是因爲你談論「通過記憶跟隨鏈接列表」。這裏沒有。 –

+0

是的,你是對的。我將更正答案 – Dessus

+0

你的子彈#2似乎也在討論鏈表,儘管它並沒有這樣說。 –

相關問題