2

我有一些我编写的代码遵循下面的基本模式。我正在寻找是否有更好、更简洁或性能更好的想法来实现相同的目标。目标是将一个列表中的项目与另一个列表中的项目进行比较,并在它们匹配时执行操作。我让它工作的唯一方法是下面的想法,但我是 c# 和 .net 的新手,我不确定是否有更好的方法。

list A
list B
int counter;
int counter2;
while (counter < comparison item)
{
    while (counter2 < comparison item 2)
    {
        if (A[counter] == B[counter2])
        {
            // do stuff
        }
        counter2++;
    }
    counter++;
}
4

2 回答 2

3

这种双循环结构很简单,但性能不高。问题是比较的次数:如果第一组有N项目,第二组有M,那么就会有N*M比较。每组有 1,000 个项目,我们谈论的是 1,000,000 次比较。

更好的方法是散列第一组的项目,然后在散列中搜索第二组的项目。由于散列是在摊销的常数时间内完成的,因此您可以在操作中执行此M+N操作,或者对于两组各 1,000 个项目大约 2,000 个:

var setA = new HashSet<int>(listA);
foreach (var b in listB) {
    if (setA.Contains(b)) {
        ...
    }
}

LINQ 库让您可以用更少的代码行来完成这项工作:

foreach (var ab in listA.Intersect(listB)) {
    ...
}
于 2013-08-21T03:00:43.470 回答
1

如果您不需要更改列表,那么您应该使用foreach循环。

foreach (var itemA in A)
{
    foreach (var itemB in B)
    {
        if (itemA == itemB) {}
    }
}

如果您确实需要更改列表,那么您应该使用for循环。

for (var i = 0; i < A.Count; i++) 
{
    for (var j = 0; j < B.Count; j++)
    {
        if (A[i] == B[j]) {}
    }
}

如果这两个列表是排序的,您可以通过按顺序浏览列表来更有效地做到这一点。

int i = 0;
int j = 0;

while (A.Length <= i && B.Length <= j)
{
    if (A[i] == B[j]) 
    {
        // items are equal
        i++;
        j++;
    }
    else if (A[i] > B[j]) // Comparison of the ordered value, could be a property on the item.
    {
        j++; // increment B's counter
    }
    else
    {
        i++; // increment A's counter
    }
}
于 2013-08-21T02:59:00.920 回答