2009-12-16 71 views
1

最優化的方式可以說我有話如下面的集合:VS2008 C#:刪除多次出現

{「你好」,「世界」,「我的」,「你好」,「世界」, 「sam」,「world」}

我想刪除任何倍數,使得解析後的結果如下所示。

{ 「你好」, 「世界」, 「我的」, 「山姆」}

我怎樣才能做到這一點在最優化的方式。

+0

哪個框架? 2.0,3.0,3.5,4? – 2009-12-16 18:00:11

+0

你認爲你需要解析多少百萬字符串? – 2009-12-16 18:13:08

+0

作業?如果是這樣,只需標記爲 – 2009-12-16 18:25:28

回答

3

如果您使用的是.NET 3.5,您可以將它們插入HashSet<T>,然後(如果您希望維護訂單)遍歷原始列表並添加哈希集中的項目。這將是爲O(n),因爲它是在單次

string[] values = new[] {"hello", "world", "my", "hello", "world", "sam", "world"}; 

HashSet<string> hashSet = new HashSet<string>(); 
List<string> newValues = new List<string>(); // or LinkedList<string>, if you don't want the cost of backing array resizes 

foreach (string val in values) { 
    if (!hashSet.Contains(val)) { 
     newValues.Add(val); 
     hashSet.Add(val); 
    } 
} 

// newValues is the result you want 

如果它是.NET 2.0,使用的Dictionary<string, object>代替HashSet<T>你得到同樣的性能,null作爲值

+1

這在空間方面是最佳的。在速度方面 - 創建空的HashSet,清空LinkedList,遍歷原始列表/數組,檢查元素是否在集合中:如果不是,則將其添加到集合和列表中。您將最終得到一個保留原始訂單的LinkedList。如果你不關心訂單,那就使用HashSet。然後在實際需要這些值時迭代它。 – 2009-12-16 18:06:22

+0

啊,這是一個更好的方法... – thecoop 2009-12-16 18:08:28

+1

這幾乎就是LINQ'Distinct'方法的工作原理,儘管'Distinct'會產生不同的值,而不是將它們添加到新列表中。 – LukeH 2009-12-16 18:17:08

0

肯定有更有效的方式,然後這個,我只是一個LINQ風扇;)

IEnumerable<string> reducedList = 
    originalList.GroupBy(s => s).Select(s => s.First()); 
8

我不知道最優化,但System.Linq.Enumerable.Distinct肯定是最簡潔的方式。

// using System.Linq; 
string[] words = {"hello", "world", "my", "hello", "world", "sam", "world"}; 
var uniqueWords = words.Distinct(); 
+1

剛剛檢查,Distinct實際上使用Set作爲其實現。 – Josh 2009-12-16 18:11:03

+0

+1,因爲這會在幕後使用正確的數據結構。 – 2009-12-16 18:18:29

0
List<string> myStrings = new List<string>(){"hello", "world", "my", "hello", "world", "sam", "world"}; 

var b = ((from a in my myStrings select a).Distinct()).ToList(); 
2

HashSet構造器會過濾列表你。

var distinctItems = new HashSet<string>((IEnumerable<string>)myItems);