2013-10-29 54 views
2

如果我有一個字符串列表,確定另一個列表中的每個元素是否包含在這個列表中的最佳方法是什麼。例如:在C#中,查看列表是否包含另一個列表的最佳方法是什麼?

List<string> list = new List<string>(); 
list.Add("Dog"); 
list.Add("Cat"); 
list.Add("Bird"); 

List<string> list2 = new List<string>(); 
list.Add("Dog"); 
list.Add("Cat"); 

if (list.ContainsList(list2)) 
{ 
     Console.Write("All items in list2 are in list1") 
} 

我想確定是否有像這樣的「ContainsList」方法?

+1

好討論這個http://stackoverflow.com/questions/332973/linq-check-whether-an-array-另一個是@leora的子集 – ojhawkins

回答

6
if (!list2.Except(list).Any()) 
+0

神奇的是它和'HashSet'解決方案一樣快。 –

4

Loved SLaks版本。爲了完整,您可以在執行設置操作時使用HashSet方法IsSubsetOf(同時檢查IsSupersetOf方法)。這種方法有利有弊。下面的代碼顯示了一個示例:

var list1 = new HashSet<string>{ "Dog", "Cat", "Bird" }; 

var list2 = new HashSet<string>{ "Dog", "Cat" }; 

if (list2.IsSubsetOf(list1)) 
{ 
     Console.Write("All items in list2 are in list1"); 
} 

Except方法本質上是流式傳輸。在查詢list2.Except(list1)list1被完全緩衝到內存中,並且通過list2一次迭代一個項目。 IsSubsetOf熱切地以相反的方式工作。當你有大量的數據時,這會開始有所作爲。


分析最壞情況下的性能,下面是Except實現在Monos Enumerable一些代碼(dotPeek給出了非常相似的結果,只是少可讀性)

var items = new HashSet<TSource> (second, comparer); //list1.Count 

foreach (var element in first)      //list2.Count 
    if (items.Add (element))       //constant time 
     yield return element; 

的結果O(list1.Count + list2.Count),循環不能嵌套。

IsSubset具有下一個方法調用,如果第二IEnumerableHashSet(經由dotPeek反編譯):

private bool IsSubsetOfHashSetWithSameEC(HashSet<T> other) 
{ 
    foreach (T obj in this)   //list2.Count 
     if (!other.Contains(obj)) //constant time 
      return false; 

    return true; 
} 

O(list2.Count)得到的IF list1HashSet

+2

使用Linq的'Except()'是一個O(mn)操作,我相信,而'HashSet.IsSubsetOf()'是O(n)。 –

+0

@NicholasCarey好,取決於定義。 'Except'接受兩個'IEnumerable',從右側構造'HashSet'並在'HashSet'上迭代左側調用'Add'方法。據我所知,這給出了「m + n」。 'Add'方法需要一段時間。 'IsSubset'有這一行'HashSet hashSet =其他爲HashSet ;'這會產生巨大的差異,不需要從'list1'構造'HashSet'。然後它只剩下'O(n)',其中n ='list1.Count'。 –

+0

@NicholasCarey Enumerable.Except'實際上在枚舉過程中創建了一個臨時哈希表。這使它成爲O(n + m),而不是O(nm)。 –

0

怎麼樣,

var list1 = new List<string>{"Dog","Cat","Bird"}; 
var list2 = new List<string>{"Dog","Cat"}; 

if (list1.Union(list2).SequenceEqual(list1)) 
    Console.Write("All items in list2 are in list1"); 
0

如何在這裏這個

list1.intersect (list2).ToList().Foreach ((x)=> 
{ 
Console.Writeline (x) 
}); 
相關問題