Scala BitSet和移位操作

时间:2011-09-07 19:54:58

标签: scala bit-shift bitset

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

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

我是否离开了实现我自己的支持移位操作的BitSet类的唯一选择?此外,根据3中给出的描述,听起来难以支持Scala的BitSet实现上的移位操作,或者我在这里误解了什么?

提前致谢。

2 个答案:

答案 0 :(得分:5)

面对需要改进新功能的常用技巧是“皮条客我的图书馆”模式。将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,那么访问原始底层数组的一种(略微hacky)方法是模式匹配。也不是太痛苦,因为只有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 BitSet2 param不是val,而且可变BitSet的elems参数被标记为受保护。所以它并不完美,但是如果你的集合是非平凡且不可变的,那么应该这样做。对于琐碎的案例,对该集合的“正常”访问不会太昂贵。

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

答案 1 :(得分:-3)

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

import collection.immutable.BitSet
val bitSet = BitSet(1,2,3)
bitSet map (_ + 4)
相关问题