现在有三个选项 - 前两个选项比较一般, 因为它们不依赖正在排序的 < code> millionIntegerList (原未指明)。 在大列表 < em> is em > 已经排序的情况下, 第三种选项更可取 。
<强 > 备选1 强 >
使用LINQ(LINQ),
var common = MillionIntegerList.Intersect(TwoThousandIntegerList).ToList();
这将在内部使用 HashSet<int>
所建的 two Thousand IntegerList
, 然后在其中查找 millionIntegerList
的每一个元素 - 这将比每次翻遍 two ThousandIntegerList
整个 有效得多。
如果您只想要非黑名单,您需要:
var valid = MillionIntegerList.Except(TwoThousandIntegerList).ToList();
请注意,如果您只需要一次复制结果, 您就应该删除 < code> ToList code> 调用 < code> to list code> 调用 - 我将它包括在内, 以便实现结果, 从而可以便宜地进行多次检查。 如果您只是重复使用, 除 < / code > 外, < code > 或 < code > 的返回值只会 < em> 流出结果, 从而在记忆使用方面更便宜。
<强 > 备选2 强 >
如果您不想依赖 LINQ 对对象的实施细节, 但是您仍然想要基于散列的方法 :
var hashSet = new HashSet<int>(TwoThousandIntegerList);
hashSet.IntersectWith(MillionIntegerList);
// Now use hashSet
<强 > 备选3 强 >
使用对大名单进行分类的做法肯定是有益的。
假设您不介意先对黑名单进行排序, 您可以写出类似( 未测试的)流( 和一般目的) 执行 :
// Note: to use this, you d need to make sure that *both* sequences are sorted.
// You could either sort TwoThousandIntegerList in place, or use LINQ s OrderBy
// method.
public IEnumerable<T> SortedIntersect<T>(this IEnumerable<T> first,
IEnumerable<T> second) where T : IComparable<T>
{
using (var firstIterator = first.GetEnumerator())
{
if (!firstIterator.MoveNext())
{
yield break;
}
using (var secondIterator = second.GetEnumerator())
{
if (!secondIterator.MoveNext())
{
yield break;
}
T firstValue = firstIterator.Current;
T secondValue = secondIterator.Current;
while (true)
{
int comparison = firstValue.CompareTo(secondValue);
if (comparison == 0) // firstValue == secondValue
{
yield return firstValue;
}
else if (comparison < 0) // firstValue < secondValue
{
if (!firstIterator.MoveNext())
{
yield break;
}
firstValue = firstIterator.Current;
}
else // firstValue > secondValue
{
if (!secondIterator.MoveNext())
{
yield break;
}
secondValue = secondIterator.Current;
}
}
}
}
}
(如果您想要使用 Icomparer<T>
,而不是以T为类比,您可以使用 Icomparer<T>
。 )