Scala BitSet 和移位操作

标签 scala bit-shift bitset

我正在寻找一种方法来用一个位向量(这将是该组整数的特征函数)表示一组整数,并能够对该组执行按位运算。

最初我认为 scala 的 BitSet 是理想的选择。但是,根据文档 1,BitSet 似乎不支持移位操作。 .经过进一步调查,我还发现相关的 Java BitSet 实现也不支持移位操作 2 .

我是否只剩下实现自己的支持移位操作的 BitSet 类的唯一选择?此外,根据3中给出的描述在 Scala 的 BitSet 实现上支持移位操作听起来并不难,还是我误解了什么?

提前致谢。

最佳答案

当需要改造新功能时,常用的技巧是“拉皮条我的图书馆”模式。将 BitSet 隐式转换为旨在执行添加操作的专用类型:

class ShiftableBitSet(bs: BitSet) {
  def shiftLeft(n: Int): BitSet = ... //impl goes here
}

implicit def bitsetIsShiftable(bs: BitSet) = new ShiftableBitSet(bs)

val sample = BitSet(1,2,3,5,7,9)
val shifted = sample.shiftLeft(2)

shiftLeft 更改为您喜欢的任何名称和任何参数。

更新

如果您确定您将拥有一个不可变的 BitSet,那么访问原始底层数组的一种(有点老套)方法是模式匹配。也不太痛苦,因为不可变的 BitSet 只有 3 个可能的具体子类:

import collection.immutable.BitSet
val bitSet = BitSet(1,2,3)
bitSet match {
  case bs: BitSet.BitSet1 => Array(bs.elems)
  case bs: BitSet.BitSetN => bs.elems 
  case _ => error("unusable BitSet")
}

令人讨厌的是,BitSet2elems1 参数不是 val,而可变 BitSet 的 elems 参数被标记为 protected 。所以它并不完美,但如果你的集合不平凡且不可变,它应该可以解决问题。对于微不足道的情况,对集合的“正常”访问不会太昂贵。

是的,这种技术将在如上所述的包装器中使用。

关于Scala BitSet 和移位操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7339782/

相关文章:

c - 将 fwrite() 与霍夫曼编码一起使用 - 位移位和位操作

matlab - Matlab 中的非循环移位?

scala - Slick:通过获取列名查询多个表/数据库

json - 如何使用 Hcursor 或 Optics 作为 Circe-Json 的一部分返回匹配对象的列表?

java - 如何在scala repl中加载和使用 native 库?

C 奇怪的换档行为

java - 在java中创建特定长度的BitSet

java - 调整 java BitSet 的大小

java - 为什么不使用更具大小确定性的类型来实现 BitSet?

scala - TDD Scala 教程