【问题标题】:Efficient lookup for objects in a list with large arrays as member elements以大型数组作为成员元素的列表中的对象的高效查找
【发布时间】:2012-05-22 00:18:45
【问题描述】:

你好,我有一门课

class State
{
    int[] some_array;
    //some other members
}

现在我需要比较两个 State 对象是否相同。如果它们具有相同的some_array 与对象的其他成员无关,我定义了两个相同的状态。

现在我有一个包含数千个 State 对象的列表。如何有效地获取一个状态并通过查找找出列表中存在的另一个类似状态?

我可以将列表中每个状态元素的some_array 数组与给定的状态对象进行比较。但这需要大量计算 O(N*size of some_array)。如何以最少的计算量做到这一点?

注意:在每种情况下,除了一个数组权利之外的所有权利几乎相同。因此,查找可以深入到数组中。

【问题讨论】:

  • 如果两个some_array成员只有相同的项目,他们是否被视为相等,或者他们必须以相同的顺序拥有相同的项目?

标签: c# arrays performance list


【解决方案1】:

我不确定这是否可能,但在您的数组中创建内容的哈希对我来说是一个不错的解决方案。这样您就可以只比较哈希值,而不是遍历整个数组并比较每个单独的值。

【讨论】:

  • 确实如此。只需覆盖GetHashCode 并使其返回数组的哈希值,并实现Equals 以便检查内部数组是否相等。然后一个简单的Dictionary<TKey, TValue> 就可以完成剩下的工作。
  • 不一定。 GetHashCode() 在 .Net 框架中有一个非常特殊的用途。确保此域特定定义和 .NET 假设之间的相等语义兼容(哈希码可用于 Dictionary / HashSet 成员资格)。
  • 如果要重新定义object.Equals,重新定义GetHashCode 是有意义的。如果通过覆盖Equals 来实现它是有意义的,那么实现GetHashCode 应该没有问题(只要你遵守规则:msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx)。如果没有,而这只是您正在进行的某种比较,那么您可能会尝试以另一种方式散列,但不要覆盖 GetHashCode
  • 嗨,如果我在构建状态时创建了一个数组元素字符串并将它们作为成员存储在 State 类中会怎样?那么我将不得不只比较字符串。会更快吗?
【解决方案2】:

假设顺序很重要,您的算法是 O(N)最坏情况。如果不同状态的值往往不同,则在比较两个候选者的元素时,测试通常会很早就失败。如果数据是完全随机的,那么将两个状态相互比较的性能将接近 O(1)……第一个数组元素大部分时间会有所不同,前两个相同的几率会小得多,等等。如果您对数组中的数据结构有所了解(例如,最后可能最有可能不同?)您可以利用它。当然数组长度可以不同,先检查一下。

如果数组在初始化后不会改变,你可以预先计算数组元素的哈希值。但是,除非我的第一条语句不适用(您通常会在检测到差异之前深入到数组中),否则哈希可能不是最佳选择。

【讨论】:

  • 是的,订单很重要。实际上,在每种情况下,除了一个数组元素之外的所有元素几乎都是相同的。所以查找可以深入到数组中。
猜你喜欢
  • 2017-09-14
  • 2018-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-09
相关资源
最近更新 更多