繁体   English   中英

查找两个列表之间的差异数

[英]Find the number of differences between two lists

我想比较两个具有相同元素数量的列表,并找出它们之间的差异数量。 现在,我有以下代码(有效):

public static int CountDifferences<T> (this IList<T> list1, IList<T> list2)
{
    if (list1.Count != list2.Count)
        throw new ArgumentException ("Lists must have the same number of elements", "list2");

    int count = 0;
    for (int i = 0; i < list1.Count; i++) {
        if (!EqualityComparer<T>.Default.Equals (list1[i], list2[i]))
            count++;
    }

    return count;
}

这让我感到混乱,而且似乎必须有一种更优雅的方法来实现它。 是否有办法将两个列表合并为一个元组列表,然后简单地检查新列表的每个元素以查看两个元素是否相等?

由于列表中的顺序确实算在内,这是我的方法:

public static int CountDifferences<T>(this IList<T> list1, IList<T> list2)
{
    if (list1.Count != list2.Count)
        throw new ArgumentException("Lists must have the same number of elements", "list2");

    int count  = list1.Zip(list2, (a, b) => a.Equals(b) ? 0 : 1).Sum();
    return count;
}

只需使用Enumerable.Zip()合并列表,然后将差异加总仍为O(n),但这只会枚举列表一次。

同样,由于我们不使用列表索引器(显然在保护检查中的计数比较中也是如此),因此该方法也可以在相同类型的任何两个IEnumerable上使用。

尝试这样的事情:

var result = list1.Intersect(list2);
var differences = list1.Count - result.Count();

如果订单很重要:

var result = a.Where((x,i) => x !=b[i]);
var differences = result.Count();

我认为您的方法很好,但是您可以使用LINQ简化功能:

public static int CountDifferences<T>(this IList<T> list1, IList<T> list2)
{
    if(list1.Count != list2.Count)
        throw new ArgumentException("Lists must have same # elements", "list2");
    return list1.Where((t, i) => !Equals(t, list2[i])).Count();
}

您在问题中的书写方式,我认为Intersect不会满足您的需求。 例如,假设您有:

var list1 = new List<int> { 1, 2, 3, 4, 6, 8 };
var list2 = new List<int> { 1, 2, 4, 5, 6, 8 };

如果您运行list1.CountDifferences(list2) ,那么我假设您要取回2,因为元素2和3不同。 在这种情况下, Intersect将返回5,因为列表共有5个元素。 因此,如果您要查找5,则Intersect是必经之路。 如果要返回2,则可以使用上面的LINQ语句。

您可以使用List的扩展方法Zip。

List<int> lst1 = new List<int> { 1, 2, 3, 4, 5 };
List<int> lst2 = new List<int> { 6, 2, 9, 4, 5 };
int cntDiff = lst1.Zip(lst2, (a, b) => a != b).Count(a => a);

// Output is 2

您需要Enumerable的Intersect扩展方法。

public static int CountDifferences<T> (this IList<T> list1, IList<T> list2)
{
    if (list1.Count != list2.Count)
        throw new ArgumentException ("Lists must have the same number of elements", "list2");

    return list1.Count - list1.Intersect(list2).Count();
} 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM