我有一个集合,它是两个唯一订单的排列,其中 OrderId 是唯一的。因此它包含 Order1 (Id = 1)
和 Order2 (Id = 2)
作为12
和 21
.现在在处理路由算法时,检查的条件很少,而最终结果中包含组合,则必须忽略它的反向,不需要考虑处理。现在,由于 Id 是一个整数,我创建了以下逻辑:
private static int GetPairKey(int firstOrderId, int secondOrderId)
{
var orderCombinationType = (firstOrderId < secondOrderId)
? new {max = secondOrderId, min = firstOrderId}
: new { max = firstOrderId, min = secondOrderId };
return (orderCombinationType.min.GetHashCode() ^ orderCombinationType.max.GetHashCode());
}
在逻辑中,我创建了一个 Dictionary<int,int>
,其中 key 是使用方法 GetPairKey
创建的如上所示,我确保在给定的组合中它们被正确排列,以便我得到相同的哈希码,可以将其插入并检查字典中的条目,而它的值是虚拟的并被忽略。
但是上面的逻辑似乎有一个缺陷,它没有按预期的方式处理所有的逻辑处理,在这种情况下我做错了什么,我应该尝试一些不同的东西来创建一个Hashcode
吗? .像下面的代码是更好的选择吗,请建议
Tuple.Create(minOrderId,maxOrderId).GetHashCode
, 以下是相关代码用法:
foreach (var pair in localSavingPairs)
{
var firstOrder = pair.FirstOrder;
var secondOrder = pair.SecondOrder;
if (processedOrderDictionary.ContainsKey(GetPairKey(firstOrder.Id, secondOrder.Id))) continue;
添加到Dictionary,是下面的代码:
processedOrderDictionary.Add(GetPairKey(firstOrder.Id, secondOrder.Id), 0);
这里的值 0 是虚拟的,没有被使用
最佳答案
您需要一个可以唯一表示每个可能值的值。
这与哈希码不同。
您可以使用 long
或包含所有适当值的类或结构来唯一地表示每个值。由于在达到一定的总大小后,使用 long
将不再有效,让我们看看另一种更灵活、更可扩展的方法:
public class KeyPair : IEquatable<KeyPair>
{
public int Min { get; private set; }
public int Max { get; private set; }
public KeyPair(int first, int second)
{
if (first < second)
{
Min = first;
Max = second;
}
else
{
Min = second;
Max = first;
}
}
public bool Equals(KeyPair other)
{
return other != null && other.Min == Min && other.Max == Max;
}
public override bool Equals(object other)
{
return Equals(other as KeyPair);
}
public override int GetHashCode()
{
return unchecked(Max * 31 + Min);
}
}
现在,此处的 GetHashCode()
将不是唯一的,但 KeyPair
本身将是唯一的。理想情况下,散列码彼此之间会有很大不同,以便更好地分布这些对象,但比上述方法做得更好取决于有关实际值的信息,这些信息将在实践中看到。
字典将使用它来查找项目,但它也会使用 Equals
在散列码相同的那些之间进行选择。
(您可以通过使用 GetHashCode()
始终只返回 0
的版本来对此进行试验。它的性能会很差,因为冲突会影响性能,这会总是会发生碰撞,但它仍然会起作用。
关于c# - 为两个订单 ID 的排列创建唯一哈希码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33876955/