搜索列表中的现有对象

时间:2015-04-04 14:39:07

标签: c# arrays list contains exists

这是我在这里的第一个问题所以我希望我做对了 我必须创建一个整数数组的列表:

List<int[]> finalList = new List<int[]>();

为了存储具有N个数字的K个元素的所有组合。

例如:

N=5, K=2 => {1,2},{1,3},{1,4},...

一切都很好,但我想避免在列表中重复相同的组合(例如{1,2}{2,1})。因此,在将tmpArray(我暂时存储新组合)添加到列表中之前,我想检查它是否已经存储。

这就是我正在做的事情:

  • 使用下一个组合创建tmpArray(确定)
  • sort tmpArray(OK)
  • 检查List是否已包含带有以下代码的tmpArray:

    if (!finalList.Contains(tmpArray))
        finalList.Add(tmpArray);
    

但它不起作用。任何人都可以帮我解决这个问题吗?

2 个答案:

答案 0 :(得分:2)

Array是一种引用类型 - 您的Contains查询将无法执行您想要的操作(按顺序比较所有成员)。

您可以使用以下内容:

if (!finalList.Any(x => x.SequenceEqual(tmpArray))
{
    finalList.Add(tmpArray);
}

(确保在文件顶部添加using System.Linq

我建议您了解有关value vs. reference types,Linq和C#数据结构基础知识的更多信息。虽然上面的查询应该工作,但它会很慢 - O(n * m)其中n =每个数组finalListm长度的数组数。

对于较大的阵列,一些预先计算(例如每个阵列的哈希码)可以让您更快地进行比较,这可能是有益的。

答案 1 :(得分:0)

如果我没记错的话,contains会检查值数据类型的值,或者它会检查对象类型的地址。数组是对象类型,因此contains仅检查内存中的地址是否存储在列表中。您必须检查此列表中的每个项目并执行某种类型的算法以检查数组的值是否在列表中。

想到Linq,Lambda或暴力检查。

BrokenGlass对Linq和Lambda给出了一个很好的建议。

蛮力:

bool itemExists = true;
foreach (int[] ints in finalList)
{
    if (ints.Length != tmpArray.Length)
    {
        itemExists = false;
        break;
    }
    else
    {
        // Compare each element
        for (int i = 0; i < tmpArray.Length; i++)
        {
            if (ints[i] != tmpArray[i])
            {
                itemExists = false;
                break;
            }
        }

        // Have to check to break from the foreach loop
        if (itemExists == false)
        {
            break;
        }
    }
}

if (itemExists == false)
{
    finalList.add(tmpArray);
}