2009-08-26 84 views
5

我遇到的問題是從列表中刪除重複項(List)的最有效方法。從列表中刪除重複的字符串(.NET 2.0!)

我目前的實現是雙foreach循環檢查每個對象的實例數只有1,否則刪除第二個。

我知道那裏有很多其他問題,但他們都是最好的解決方案需要以上.net 2.0,這是我正在工作的當前構建環境。(GM和克萊斯勒非常抗拒變化... :))

這限制了可能的結果,因爲不允許任何LINQ或HashSets。

我正在使用的代碼是Visual C++,但C#解決方案也可以正常工作。

謝謝!

回答

15

這可能是不是你要找的東西,但如果你有在這個控制,最有效的方法是不添加它們擺在首位...

你有控制權這個?如果是這樣,您需要做的就是在添加項目之前撥打myList.Contains(currentItem),然後設置

+0

哈,我從來沒有想過,我確實控制了最初的列表代! – greggorob64 2009-08-26 15:35:49

+0

哈哈。那就是WIN! – Alan 2009-08-26 15:36:43

+1

請注意,隨着列表大小的增加,此方法無法很好地擴展... – Lee 2009-08-26 15:41:07

9

您可以執行以下操作。

List<string> list = GetTheList(); 
Dictionary<string,object> map = new Dictionary<string,object>(); 
int i = 0; 
while (i < list.Count) { 
    string current = list[i]; 
    if (map.ContainsKey(current)) { 
    list.RemoveAt(i); 
    } else { 
    i++; 
    map.Add(current,null); 
    } 
} 

這有建設Dictionary<TKey,TValue>對象,將複製列表中的唯一值的列表的開銷。但它的速度相當有效。

+0

+1首先想到的是將每個值與其他值進行比較,同時刪除找到的重複值,但其複雜度爲N^2。 Jared的解決方案更好,因爲通過使用Dicitonary數據結構將使用哈希,因此可以非常快地查找。複雜性= N(log N)? – 2009-08-26 15:40:07

+0

如果速度很重要,您最好創建一個新的唯一值列表,而不是從原始列表中刪除重複項,因爲RemoveAt是O(n),但當您知道最大長度時,Add爲O(1) 。 – stevemegson 2009-08-26 15:41:59

1

我不是Comp Sci PhD,但我想象一下使用字典,將列表中的項目作爲關鍵字會很快。

由於字典不允許重複鍵,所以在迭代結束時只有唯一的字符串。

1

只要記住提供自定義類以覆蓋Equals()方法以使Contains()按需運行即可。

List<CustomClass> clz = new List<CustomClass>() 

public class CustomClass{ 

    public bool Equals(Object param){ 
     //Put equal code here... 
    } 
} 
1

如果你要去的「只是不添加重複」的路線,然後加入工作項目之前檢查「List.Contains」,但其爲O(n^2)其中n是你想添加的數字串。它與使用兩個嵌套循環的當前解決方案沒有區別。

你會用一個HashSet來存儲您已經添加的項目有更好的運氣,但因爲你是使用.NET 2.0,一個字典可以替代的哈希集:

static List<T> RemoveDuplicates<T>(List<T> input) 
{ 
    List<T> result = new List<T>(input.Count); 
    Dictionary<T, object> hashSet = new Dictionary<T, object>(); 
    foreach (T s in input) 
    { 
     if (!hashSet.ContainsKey(s)) 
     { 
      result.Add(s); 
      hashSet.Add(s, null); 
     } 
    } 
    return result; 
} 

這將運行在O(n)中並使用O(2n)空間,對於高達100K的項目,它通常工作得非常好。實際性能取決於字符串的平均長度 - 如果您確實需要最高性能,則可以利用一些更強大的數據結構,例如嘗試使插入更快。

+0

HashSet的.net 3.5+,這是超出了這個問題的範圍。 – greggorob64 2009-08-26 16:12:13

+2

我的代碼不使用HashSet,它使用一個替代爲HashSet的字典。 – Juliet 2009-08-26 16:28:24

+0

我應該更仔細地閱讀你的代碼,我只看到了單詞HashSet,並跳過它。 – greggorob64 2009-08-26 17:27:37

相關問題