我遇到的問題是從列表中刪除重複項(List)的最有效方法。從列表中刪除重複的字符串(.NET 2.0!)
我目前的實現是雙foreach循環檢查每個對象的實例數只有1,否則刪除第二個。
我知道那裏有很多其他問題,但他們都是最好的解決方案需要以上.net 2.0,這是我正在工作的當前構建環境。(GM和克萊斯勒非常抗拒變化... :))
這限制了可能的結果,因爲不允許任何LINQ或HashSets。
我正在使用的代碼是Visual C++,但C#解決方案也可以正常工作。
謝謝!
我遇到的問題是從列表中刪除重複項(List)的最有效方法。從列表中刪除重複的字符串(.NET 2.0!)
我目前的實現是雙foreach循環檢查每個對象的實例數只有1,否則刪除第二個。
我知道那裏有很多其他問題,但他們都是最好的解決方案需要以上.net 2.0,這是我正在工作的當前構建環境。(GM和克萊斯勒非常抗拒變化... :))
這限制了可能的結果,因爲不允許任何LINQ或HashSets。
我正在使用的代碼是Visual C++,但C#解決方案也可以正常工作。
謝謝!
這可能是不是你要找的東西,但如果你有在這個控制,最有效的方法是不添加它們擺在首位...
你有控制權這個?如果是這樣,您需要做的就是在添加項目之前撥打myList.Contains(currentItem)
,然後設置
您可以執行以下操作。
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>
對象,將複製列表中的唯一值的列表的開銷。但它的速度相當有效。
+1首先想到的是將每個值與其他值進行比較,同時刪除找到的重複值,但其複雜度爲N^2。 Jared的解決方案更好,因爲通過使用Dicitonary數據結構將使用哈希,因此可以非常快地查找。複雜性= N(log N)? – 2009-08-26 15:40:07
如果速度很重要,您最好創建一個新的唯一值列表,而不是從原始列表中刪除重複項,因爲RemoveAt是O(n),但當您知道最大長度時,Add爲O(1) 。 – stevemegson 2009-08-26 15:41:59
我不是Comp Sci PhD,但我想象一下使用字典,將列表中的項目作爲關鍵字會很快。
由於字典不允許重複鍵,所以在迭代結束時只有唯一的字符串。
只要記住提供自定義類以覆蓋Equals()方法以使Contains()按需運行即可。
例
List<CustomClass> clz = new List<CustomClass>()
public class CustomClass{
public bool Equals(Object param){
//Put equal code here...
}
}
如果你要去的「只是不添加重複」的路線,然後加入工作項目之前檢查「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的項目,它通常工作得非常好。實際性能取決於字符串的平均長度 - 如果您確實需要最高性能,則可以利用一些更強大的數據結構,例如嘗試使插入更快。
HashSet的.net 3.5+,這是超出了這個問題的範圍。 – greggorob64 2009-08-26 16:12:13
我的代碼不使用HashSet,它使用一個替代爲HashSet的字典。 – Juliet 2009-08-26 16:28:24
我應該更仔細地閱讀你的代碼,我只看到了單詞HashSet,並跳過它。 – greggorob64 2009-08-26 17:27:37
哈,我從來沒有想過,我確實控制了最初的列表代! – greggorob64 2009-08-26 15:35:49
哈哈。那就是WIN! – Alan 2009-08-26 15:36:43
請注意,隨着列表大小的增加,此方法無法很好地擴展... – Lee 2009-08-26 15:41:07