2012-02-07 42 views
1

考慮,我們有這三個名單列表:Linq查詢列表中包含有相同的順序

List<string> l1= new List<string>(){"A","B","C"}; 
    List<string> l2= new List<string>(){"A","C","B"}; 

    List<string> l3= new List<string>(){"B","C"}; 

我需要LINQ查詢其說L1包括L3但L2不。

+0

會有重複嗎? – BrokenGlass 2012-02-07 21:07:26

+0

是的,我們可能有重複。 – Behnam 2012-02-07 22:02:28

回答

6

尊重秩序和帳戶可能重複的元素,你必須枚舉的順序,這樣做將是檢查的每一個方式,在源枚舉起始位置,如果其他序列開始,例如使用擴展方法:

public static bool ContainsSequence<T>(this IEnumerable<T> source, 
             IEnumerable<T> other) 
{ 
    int count = other.Count(); 

    while (source.Any()) 
    { 
     if (source.Take(count).SequenceEqual(other)) 
      return true; 
     source = source.Skip(1); 
    } 
    return false; 
} 

需要注意的是,這將是爲O(n ),因爲最壞的情況下你已經完全列舉other枚舉爲source集合中的每個項目。

現在你可以這樣做:

List<string> l1 = new List<string>() { "A", "B", "C" }; 
List<string> l2 = new List<string>() { "A", "C", "B" }; 
List<string> l3 = new List<string>() { "B", "C" }; 

bool l1ContainsL2 = l1.ContainsSequence(l2); //returns false 
bool l1ContainsL3 = l1.ContainsSequence(l3); //returns true 
2

應該只是:

l1.Intersect(l3).Except(l2); 

注:
取決於L2的尺寸和L3相反的順序可能是更有效。
考慮到你的特定值,沒有任何東西會被返回,因爲l1中沒有任何東西不在l3中。

2

Exclaimer:作爲BrokenGlass指出,目前還不清楚這是什麼意思,一個列表包含另一個。在這裏,我允許包含序列在包含序列的項目之間添加其他項目。

快速打字而言,不太有效的:

bool l1contains = l1.Where(x => l3.Contains(x)).ToList().SequenceEqual(l3); 
bool l2contains = l2.Where(x => l3.Contains(x)).ToList().SequenceEqual(l3); 

更有效的 - 如有效,因爲它可以是運行在O(M + N),其中m,n的列表的長度。

private static bool ContainsOrdered<T>(IEnumerable<T> containing, IEnumerable<T> contained) 
{ 
    var e1 = containing.GetEnumerator(); 
    var e2 = contained.GetEnumerator(); 
    bool hasmore1 = e1.MoveNext(); 
    bool hasmore2 = e2.MoveNext(); 

    while (hasmore1 && hasmore2) 
    { 
     while (hasmore1 && !e1.Current.Equals(e2.Current)) 
      hasmore1 = e1.MoveNext(); 
     if (hasmore1) // Currents are equal 
     { 
      hasmore1 = e1.MoveNext(); 
      hasmore2 = e2.MoveNext(); 
     } 
    } 

    return !hasmore2; 
} 

bool contains1 = ContainsOrdered(l1, l3); 
bool contains2 = ContainsOrdered(l2, l3); 
+0

不正確,因爲它會匹配例如對於l1 ='{1,2,4,3}'和l2 ='{1,2,3}' – BrokenGlass 2012-02-07 21:32:37

+0

@BrokenGlass這就是重點,不是嗎?那是什麼l1含有l2意味着,在我看來 – voidengine 2012-02-07 21:46:00

+0

我認爲它意味着只有*連續*序列匹配 - 但你可能是對的。 OP應澄清 – BrokenGlass 2012-02-07 21:50:19