Scala BitSet 和移位操作

发布于 2024-12-03 11:02:04 字数 606 浏览 4 评论 0原文

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

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

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

提前致谢。

I'm looking for a way to represent a set of integers with a bit vector (which would be the characteristic function of that set of integers) and be able to perform bitwise operations on this set.

Initially I thought scala's BitSet would be the ideal candidate. However, it seems BitSet doesn't support shifting operations according to the documentation 1. Upon further investigation I also found that the related Java BitSet implementation doesn't support shift operations either 2.

Am I left with the only option of implementing my own BitSet class which supports shift operations? Moreover, according to the description given in 3 it doesn't sound that difficult to support shift operations on the Scala's BitSet implementation, or have I misunderstood something here?

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

变身佩奇 2024-12-10 11:02:04

当需要改进新功能时,常用的技巧是“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 更改为您喜欢的任何名称和任何参数。

更新

如果您确定您将拥有一个不可变的BitSet,那么访问原始底层数组的一种(有点hacky)方法是模式匹配。也不是太痛苦,因为不可变的 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 参数被标记为受保护。所以它并不完美,但如果你的集合不平凡且不可变,应该可以解决问题。对于简单的情况,“正常”访问该集合不会太昂贵。

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

The usual trick when faced with a need for retrofitting new functionality is the "Pimp My Library" pattern. Implicitly convert the BitSet to a dedicated type intended to perform the added operation:

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)

Alter shiftLeft to whatever name and with whatever arguments you prefer.

UPDATE

If you know for certain that you'll have an immutable BitSet, then a (slightly hacky) approach to access the raw underlying array is to pattern match. Not too painful either, as there are only 3 possible concrete subclasses for an immutable 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")
}

Annoyingly, the elems1 param to BitSet2 isn't a val, and the elems param to a mutable BitSet is marked protected. So it's not perfect, but should do the trick if your set is non-trivial and immutable. For the trivial cases, "normal" access to the set won't be too expensive.

And yes, this technique would be used within the wrapper as described above.

千柳 2024-12-10 11:02:04

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

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

You can just use map, for example to shift to left by 4 positions:

import collection.immutable.BitSet
val bitSet = BitSet(1,2,3)
bitSet map (_ + 4)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文