如何在保持Scala中的功能样式的同时为大的“n”值运行以下代码?

时间:2016-11-02 18:38:01

标签: scala functional-programming

 Seq.fill(n)(math.pow(Random.nextFloat,2) + math.pow(Random.nextFloat,2)).filter(_<1).size.toFloat/n*4 

这个scala代码基本上会检查随机点从单位圆的第一象限出来的次数。对于较大的n值,此代码会超出内存限制错误,因为它需要太大的序列。我可以写这种java方式。但是有没有一些功能性的方法来实现这个任务呢?

2 个答案:

答案 0 :(得分:3)

如果使用Iterator,则不必在内存中创建中间集合。

Iterator.fill(n)(math.pow(Random.nextFloat,2) + math.pow(Random.nextFloat,2)).filter(_<1).size.toFloat/n*4

答案 1 :(得分:0)

在填充序列后,不要过滤小于1的值,而应考虑在列表中添加有效数字(即大于或等于1的数字)。从而节省了对集合的不必要的迭代。

def nums(n: Int): Iterator[Float] = {
  import scala.util.Random
  def helper(items: Iterator[Float], counter: Int): Iterator[Float] = {
    val num =  math.pow(Random.nextFloat,2) + math.pow(Random.nextFloat,2)
    if (counter > 0) {
      if (num >= 1) helper( items ++ Iterator(num.toFloat), counter - 1) else helper(items, counter - 1)
    } else items
  }
  helper(Iterator[Float](), n)
}

最终答案

nums(n).toFloat/(n * 4)

Scala REPL

scala> def nums(n: Int): Iterator[Float] = {
     |       import scala.util.Random
     |       def helper(items: Iterator[Float], counter: Int): Iterator[Float] = {
     |         val num =  math.pow(Random.nextFloat,2) + math.pow(Random.nextFloat,2)
     |         if (counter > 0) {
     |           if (num >= 1) helper( items ++ Iterator(num.toFloat), counter - 1) else helper(items, counter - 1)
     |         } else items
     |       }
     |       helper(Iterator[Float](), n)
     |     }
nums: (n: Int)Iterator[Float]

scala> nums(10000).size.toFloat/(10000 * 4)
res1: Float = 0.053925