【问题标题】:Perfect hash in ScalaScala 中的完美哈希
【发布时间】:2010-05-09 09:28:46
【问题描述】:

我有一些 C 类:

class C (...) { ... }

我想用它来索引一张高效的地图。最有效的地图是一个数组。 所以我在伴生对象中添加了一个“全局”“静态”计数器,为每个对象提供唯一 ID:

object C {
  var id_counter = 0
}

在 C 的主构造函数中,每次创建 C 时我都想 记住全局计数器值并增加它。
问题一:怎么做?

现在我可以使用 C 对象中的 id 作为索引数组的完美哈希。 但是数组不会像 map 那样保留类型信息,即给定数组由 C 的 id 索引。

问题 2:是否有可能具有类型安全性?

更新:
问题 2 中的类型安全涉及映射索引的类型,以避免混合两个不相关的整数。 值当然是(类型)安全的..

问题 1 询问如何在默认构造函数中增加变量?
即:放在哪里?

id_counter += 1

【问题讨论】:

    标签: scala types hash scala-2.8 perfect-hash


    【解决方案1】:

    回答你的问题 2:

    case class C_Id(val asInt: Int)
    
    object C {
      private var list: ArrayBuffer[C] 
      // resizable array in scala.collection.mutable
      // you can also use ArrayList
    
      def apply(id: C_Id) = list(id.asInt) // only accepts an id of C
      ...
    }
    
    class C (...) {
      // in constructor:
      list += this
    }
    

    编辑问题1:默认构造函数只是类型的主体,除了方法和其他构造函数的定义。

    【讨论】:

    • 看起来不错,但我需要的不仅仅是申请。我不能从 Array 或 Seq 继承吗?
    • 你不能从 Array 继承,就像在 Java 中一样。只需让您的方法调用list 上的相应方法,就像apply 那样。
    • 隐式可以帮助我吗?类似于 RichString 的方式?
    • 没有。当您想为给定类型的每个 实例添加方法时,它们很有用。在这里,您处理C 伴随对象的单个实例和ArrayBuffer[C] 的单个实例。
    【解决方案2】:

    我没有看到问题。我可能会将计数器设为私有,因此 classobject C 之外的代码无法更改它。增加Int 类型的var 很简单:

    idCounter += 1
    

    数组在 Scala 中是类型安全的,因为它们是由 JVM 数组直接实现的(从 2.8 开始)。

    我怀疑我还没有真正理解你的问题......

    更新:

    大概增加构造函数中的计数器。

    至于创建一个实际完美的散列函数,我认为您并没有真正走在正确的轨道上。 (您刚刚将映射从您的实际密钥推送到您自己的代码中。)您应该阅读创建最小和/或完美哈希函数的技术。

    【讨论】:

    • 我相信是这样,前提是您在构造函数(全部)返回之前不发布值。
    【解决方案3】:

    能否将 C 的默认构造函数设为私有,并在伴随对象中提供工厂方法(可以轻松处理更新计数器)?

    【讨论】:

      猜你喜欢
      • 2023-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-26
      • 2011-11-11
      • 1970-01-01
      • 1970-01-01
      • 2022-12-05
      相关资源
      最近更新 更多