找出两个ICollection<T>
集合是否包含完全相同的条目的最快方法是什么?蛮力很明显,我想知道是否有更优雅的方法。
我们正在使用C#2.0,所以请尽可能没有扩展方法!
编辑:对于有序和无序集合,答案都很有趣,并且希望每个集合都有所不同。
答案 0 :(得分:4)
使用C5
http://www.itu.dk/research/c5/
“检查是否所有项目 提供的收藏品在这个包里 (计算多重性)。
该 要查找的项目。
如果所有项目都是真的 找到。“
[Tested]
public virtual bool ContainsAll<U>(SCG.IEnumerable<U> items) where U : T
{
HashBag<T> res = new HashBag<T>(itemequalityComparer);
foreach (T item in items)
if (res.ContainsCount(item) < ContainsCount(item))
res.Add(item);
else
return false;
return true;
}
答案 1 :(得分:3)
首先比较集合的。 Count ,如果它们具有相同的计数,则对所有元素进行强力比较。最糟糕的情况是O(n)。在这种情况下,元素的顺序必须相同。
第二种情况,订单不一样,你需要使用字典来存储集合中找到的元素数量:这是一个可能的算法
答案 2 :(得分:3)
对于有序集合,您可以使用SequenceEqual()
定义的System.Linq.Enumerable
扩展方法:
if (firstCollection.SequenceEqual(secondCollection))
答案 3 :(得分:2)
您的意思是相同的条目或相同的条目?
无论如何,假设您想要比较它们是否包含相同顺序的相同条目,“暴力”实际上是您在C#2.0中唯一的选择。我知道你的意思是非优雅,但如果原子比较本身是O(1),整个过程应该是O(N),这不是 坏。
答案 4 :(得分:1)
如果条目需要处于相同的顺序(除了相同),那么我建议 - 作为优化 - 您同时迭代两个集合并比较每个集合中的当前条目。否则,蛮力是要走的路。
哦,还有另一个建议 - 你可以为集合类重写Equals并在那里实现相等的东西(取决于你的项目)。
答案 5 :(得分:1)
同样,使用具有两组的C5库,您可以使用:
C5.ICollection<T> set1 = C5.ICollection<T> (); C5.ICollection<T> set2 = C5.ICollecton<T> (); if (set1.UnsequencedEquals (set2)) { // Do something }
C5库包含一个启发式实际上首先测试两个集合的未序列哈希码(参见C5.ICollection<T>.GetUnsequencedHashCode()
),这样如果两个集合的哈希码不相等,则不需要迭代每个项目都要测试是否平等。
另外值得注意的是C5.ICollection<T>
继承自System.Collections.Generic.ICollection<T>
,因此您可以在使用.NET接口的同时使用C5实现(尽管您可以通过.NET的吝啬接口访问较少的功能)。
答案 6 :(得分:0)
蛮力需要O(n) - 比较所有元素(假设它们已被排序),我认为这是你能做的最好的 - 除非数据的某些属性使其更容易。
我想对于未排序的情况,其O(n * n)。
在这种情况下,我认为基于merge sort的解决方案可能有所帮助。
例如,您是否可以重新建模,以便只有一个集合?或者3个集合,一个用于集合A中的集合,一个仅用于B和两个集合 - 所以如果A只和B只是空 - 那么它们是相同的...我可能会完全错误的切线这里...