3

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

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

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

提前致谢。

4

2 回答 2

6

当需要改造新功能时,通常的技巧是“Pimp My Library”模式。将 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为您喜欢的任何名称和任何参数。

更新

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

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")
}

烦人的是,elems1参数 toBitSet2不是 val,elems可变 BitSet 的参数被标记为受保护。所以它并不完美,但如果你的集合不平凡且不可变,那么它应该可以解决问题。对于琐碎的情况,对集合的“正常”访问不会太昂贵。

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

于 2011-09-07T20:28:58.683 回答
-3

您可以只使用地图,例如向左移动 4 个位置:

import collection.immutable.BitSet
val bitSet = BitSet(1,2,3)
bitSet map (_ + 4)
于 2015-12-25T12:53:41.740 回答