【发布时间】:2021-03-18 10:48:32
【问题描述】:
我有很多 4 个数字的列表,[0,1,2,1], [5,1,3,1], [0,1,2,0]. [0,1,2,1],...
列表包含重复项。
我正在逐步迭代列表并检查是否已经迭代了相同的列表。在大写的情况下,第一个和最后一个列表是相同的。
目前我通过将列表添加到 HashSet 来做到这一点:
HashSet<string> visited = new HashSet<string>();
string key = string.Joint(";", listOfNumbers);
if(visited.Contains(key)){
dosomething...
visited.Add(key);
}
我注意到将整数转换为字符串并检查哈希集中是否存在此类字符串对于大型集合可能会很慢。如果我改用整数,即 int keys = (number1) * 1000000 + (number2) * 10000 + (number3) * 100 + (number4);,它会快 1/3,但这个键对于大数来说不一定是唯一的。
我认为,我缺少一些为数字列表创建唯一键并以某种方式检查重复项的基本知识。有没有比使用字符串更有效的方法来解决这个问题?
【问题讨论】:
-
您的数字可以有多大?如果它可以大于某个数字,那么就没有唯一键。
-
您已经理解了
GetHashCode的用途,所以请多阅读!最好的解决方案是使用为您的数组生成合适的哈希码的数据结构,而无需将其转换为字符串的成本。一个 4 元素元组可以工作(例如HashSet<(int a, int b, int c, int d)>),或者一个包装每个 4 元素数组的自定义结构。也不要使用.Contains然后.Add:.Add返回一个值,说明 HashSet 是否已经包含该值,所以使用它 -
整个哈希码系统已经有了最初使用单个 int 作为查找的逻辑,然后如果你得到两个具有相同 int 查找的元素,则回退到正确检查相等性。这就是
HashSet<T>已经在做的事情。值得学习如何正确使用它。 -
这就是 IequalityComparer(参见:docs.microsoft.com/en-us/dotnet/api/…)同时具有哈希和比较方法的原因。
-
在 .NET 5 中你可以使用
HashCode.Combine
标签: c#