2012-02-07 44 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