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++;
}
}
}
}