Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在不同类型的集合之间获得匹配?_C#_Linq_Algorithm_Optimization_Collections - Fatal编程技术网

C# 如何在不同类型的集合之间获得匹配?

C# 如何在不同类型的集合之间获得匹配?,c#,linq,algorithm,optimization,collections,C#,Linq,Algorithm,Optimization,Collections,我认为这需要O(A x B)时间来执行 (其中A是集合A的大小,B是集合B的大小) 我说得对吗 IEnumerable<A> GetMatches(IEnumerable<A> collectionA, IEnumerable<B> collectionB) { foreach (A a in collectionA) foreach (B b in collectionB) if (a.Value == b.V

我认为这需要
O(A x B)
时间来执行

(其中A是集合A的大小,B是集合B的大小)

我说得对吗

IEnumerable<A> GetMatches(IEnumerable<A> collectionA, IEnumerable<B> collectionB)
{
    foreach (A a in collectionA)
        foreach (B b in collectionB)
            if (a.Value == b.Value)
                yield return a;
}
IEnumerable GetMatches(IEnumerable collectionA、IEnumerable collectionB)
{
foreach(集合中的A)
foreach(集合B中的B)
如果(a.Value==b.Value)
收益率a;
}

有没有更快的方法执行此查询?(可能使用LINQ?

可枚举。不幸的是,Intersect
无法与两种不同的类型(
A
B
)进行比较

这将需要一些单独的处理来获得一个可以工作的Intersect调用

您可以分阶段执行此操作:

IEnumerable<A> GetMatches(IEnumerable<A> collectionA, IEnumerable<B> collectionB)
     where A : ISomeConstraintWithValueProperty
     where B : ISomeOtherConstraintWithSameValueProperty
{
    // Get distinct values in A
    var values = new HashSet<TypeOfValue>(collectionB.Select(b => b.Value));

    return collectionA.Where(a => values.Contains(a.Value));
}

如果对数据进行排序,您可以尝试以下交叉算法,其复杂性为O(m+n),否则为O(nlogn),而无需消耗额外内存:

    private static IEnumerable<A> Intersect(A[] alist, B[] blist)
    {
        Array.Sort(alist);
        Array.Sort(blist);

        for (int i = 0, j = 0; i < alist.Length && j < blist.Length;)
        {
            if (alist[i].Value == blist[j].Value)
            {
                yield return alist[i];
                i++;
                j++;
            }
            else
            {
                if (alist[i].Value < blist[j].Value)
                {
                    i++;
                }
                else
                {
                    j++;
                }
            }
        }
    }
private静态IEnumerable Intersect(A[]alist,B[]blist)
{
Array.Sort(alist);
数组.Sort(blist);
对于(int i=0,j=0;i
我建议您在何时使用哪个集合,即急切地消费
collectionB
,然后流式处理
collectionA
——只是因为这更符合LINQ to Objects的其他功能。@Jon:好的一点——我也注意到了其中的一个bug(为了实现这一点,哈希集需要是对值的哈希,而不是对象本身…)这更符合您的想法?这个解决方案的复杂性如何?@asmo:更好,因为哈希集。包含的是O(1)…您仍然在枚举所有的a,但这比上面的二次方法要好得多。
    private static IEnumerable<A> Intersect(A[] alist, B[] blist)
    {
        Array.Sort(alist);
        Array.Sort(blist);

        for (int i = 0, j = 0; i < alist.Length && j < blist.Length;)
        {
            if (alist[i].Value == blist[j].Value)
            {
                yield return alist[i];
                i++;
                j++;
            }
            else
            {
                if (alist[i].Value < blist[j].Value)
                {
                    i++;
                }
                else
                {
                    j++;
                }
            }
        }
    }