从谓词在Scala中构造位集?

从谓词在Scala中构造位集?,scala,bitset,Scala,Bitset,假设我想要构造一个包含从0到n的所有整数的位集,这些整数满足某个谓词f:Int=>Boolean 我可以写这样的东西 BitSet((0 until n):_*).filter(f) 这当然有效。但这感觉相当低效!我正计划在一个非常紧密的循环中完成这项工作,并希望获得更有效的方法的建议。这是目前我能想到的最好的方法 BitSet((0 until n).view.filter(f):_*) 视图部分使过滤器方法变懒。这确保了当从给定序列创建位集时,它将动态过滤。您最初的建议是在创建第一个位集

假设我想要构造一个包含从0到n的所有整数的位集,这些整数满足某个谓词
f:Int=>Boolean

我可以写这样的东西

BitSet((0 until n):_*).filter(f)

这当然有效。但这感觉相当低效!我正计划在一个非常紧密的循环中完成这项工作,并希望获得更有效的方法的建议。

这是目前我能想到的最好的方法

BitSet((0 until n).view.filter(f):_*)

视图部分使
过滤器
方法变懒。这确保了当从给定序列创建
位集时,它将动态过滤。您最初的建议是在创建第一个
位集之后创建一个新的
位集。

这是目前我能想到的最好方法

BitSet((0 until n).view.filter(f):_*)

视图部分使
过滤器
方法变懒。这确保了当从给定序列创建
位集时,它将动态过滤。您最初的建议是在创建第一个
位集之后创建一个新的
位集。

我认为最有效的“功能”方法是使用
foldLeft

(1 to 5).foldLeft(BitSet())((s,i) => if (f(i)) s + i else s)
它不创建中间集合,而是在筛选时从头开始构造集合

我想到的第一件事是使用
breakOut
,但它不适用于
过滤器

scala> val set: BitSet = (0 until 10).filter(f)(collection.breakOut)
<console>:11: error: polymorphic expression cannot be instantiated to expected type;
 found   : [From, T, To]scala.collection.generic.CanBuildFrom[From,T,To]
 required: Int
       val set: BitSet = (0 until 10).filter(f)(collection.breakOut)
                                                           ^

scala> val set: BitSet = (0 until 10).map(_+1)(collection.breakOut)
set: scala.collection.immutable.BitSet = BitSet(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala>val集:位集=(0到10)。过滤器(f)(collection.breakOut)
:11:错误:多态表达式无法实例化为预期类型;
找到:[From,T,To]scala.collection.generic.CanBuildFrom[From,T,To]
必填项:Int
val集合:位集合=(0到10).filter(f)(collection.breakOut)
^
scala>val集:位集=(0到10.map(+1)(collection.breakOut)
set:scala.collection.immutable.BitSet=BitSet(1,2,3,4,5,6,7,8,9,10)

breakOut
也不会创建中间集合,但因为
filter
没有第二个参数列表,所以它无法工作。

我认为最有效的“功能”方法是使用
foldLeft

(1 to 5).foldLeft(BitSet())((s,i) => if (f(i)) s + i else s)
它不创建中间集合,而是在筛选时从头开始构造集合

我想到的第一件事是使用
breakOut
,但它不适用于
过滤器

scala> val set: BitSet = (0 until 10).filter(f)(collection.breakOut)
<console>:11: error: polymorphic expression cannot be instantiated to expected type;
 found   : [From, T, To]scala.collection.generic.CanBuildFrom[From,T,To]
 required: Int
       val set: BitSet = (0 until 10).filter(f)(collection.breakOut)
                                                           ^

scala> val set: BitSet = (0 until 10).map(_+1)(collection.breakOut)
set: scala.collection.immutable.BitSet = BitSet(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala>val集:位集=(0到10)。过滤器(f)(collection.breakOut)
:11:错误:多态表达式无法实例化为预期类型;
找到:[From,T,To]scala.collection.generic.CanBuildFrom[From,T,To]
必填项:Int
val集合:位集合=(0到10).filter(f)(collection.breakOut)
^
scala>val集:位集=(0到10.map(+1)(collection.breakOut)
set:scala.collection.immutable.BitSet=BitSet(1,2,3,4,5,6,7,8,9,10)

breakOut
也不会创建中间集合,但因为
filter
没有第二个参数列表,所以它无法工作。

如果性能确实是您最关心的问题,最好的选择可能是使用
mutable.BitSet
和while循环,然后对结果调用
toImmutable

val bitSet = {
  val tmp = new scala.collection.mutable.BitSet(n)
  var i = 0;
  while (i < n) {
    if (f(i)) {
      tmp += i
    }
    i = i + 1
  }
  tmp.toImmutable
}
val位集={
val tmp=new scala.collection.mutable.BitSet(n)
var i=0;
而(i
如果性能确实是您最关心的问题,那么最好的选择可能是使用
可变.BitSet
和while循环,然后对结果调用
toImmutable

val bitSet = {
  val tmp = new scala.collection.mutable.BitSet(n)
  var i = 0;
  while (i < n) {
    if (f(i)) {
      tmp += i
    }
    i = i + 1
  }
  tmp.toImmutable
}
val位集={
val tmp=new scala.collection.mutable.BitSet(n)
var i=0;
而(i
你说的不是真的,
过滤器
创建了一个中间集合,即使使用
视图
。事实上,
视图
在这里是完全无用的
:*
表示直接传递参数,而不是将其包装成一个序列。重复的参数不是“直接”传递的(如推送到参数堆栈中),而是放在一种
IndexedSeq
中,并作为单个参数传递给方法。换句话说,它们肯定是包装好的。@Randall Schulz:是的,但是schaef是对的<代码>范围
继承其
过滤器
实现,该实现来自
TraversableLike
,定义如下:。正如您所看到的,它迭代原始集合的每个元素(它只是一个
foreach
),因此即使通过
视图
使集合变懒,
过滤器
仍将强制对原始集合的每个元素求值。因此,在这种情况下,使用
视图
实际上会引入不必要的附加间接寻址,从而使情况变得更糟。您所说的是不正确的,
过滤器
创建了一个中间集合,即使使用
视图
。事实上,
视图
在这里是完全无用的
:*
表示直接传递参数,而不是将其包装成一个序列。重复的参数不是“直接”传递的(如推送到参数堆栈中),而是放在一种
IndexedSeq
中,并作为单个参数传递给方法。换句话说,它们肯定是包装好的。@Randall Schulz:是的,但是schaef是对的<代码>范围
继承其
过滤器
实现,该实现来自
TraversableLike
,定义如下:。正如您所看到的,它迭代原始集合的每个元素(它只是一个
foreach
),因此即使通过
视图
使集合变懒,
过滤器
仍将强制对原始集合的每个元素求值。因此,在这种情况下,使用
视图
实际上会引入不必要的附加间接寻址,从而使情况变得更糟。