在列表中搜索现有对象
Search for an existing object in a list
这是我的第一个问题,希望我做对了。
我必须创建一个整数数组列表:
List<int[]> finalList = new List<int[]>();
为了存储K个元素与N个数的所有组合
例如:
N=5, K=2 => {1,2},{1,3},{1,4},...
一切正常,但我想避免在列表中重复相同的组合(例如{1,2}
和{2,1}
)。因此,在列表中添加 tmpArray(我临时存储新组合的位置)之前,我想检查它是否已经存储。
这就是我正在做的事情:
- 使用下一个组合创建 tmpArray(确定)
- 对 tmpArray 进行排序(确定)
使用以下代码检查列表是否已包含 tmpArray:
if (!finalList.Contains(tmpArray))
finalList.Add(tmpArray);
但它不起作用。谁能帮我解决这个问题?
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 = finalList
中的数组数和每个数组的 m
长度。
对于较大的数组,一些允许您进行更快比较的预计算(例如,每个数组的哈希码)可能是有益的。
如果我没记错的话,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);
}
这是我的第一个问题,希望我做对了。
我必须创建一个整数数组列表:
List<int[]> finalList = new List<int[]>();
为了存储K个元素与N个数的所有组合
例如:
N=5, K=2 => {1,2},{1,3},{1,4},...
一切正常,但我想避免在列表中重复相同的组合(例如{1,2}
和{2,1}
)。因此,在列表中添加 tmpArray(我临时存储新组合的位置)之前,我想检查它是否已经存储。
这就是我正在做的事情:
- 使用下一个组合创建 tmpArray(确定)
- 对 tmpArray 进行排序(确定)
使用以下代码检查列表是否已包含 tmpArray:
if (!finalList.Contains(tmpArray)) finalList.Add(tmpArray);
但它不起作用。谁能帮我解决这个问题?
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 = finalList
中的数组数和每个数组的 m
长度。
对于较大的数组,一些允许您进行更快比较的预计算(例如,每个数组的哈希码)可能是有益的。
如果我没记错的话,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);
}