Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Scala中修复Fibonacci流_Scala_Stream_Fibonacci - Fatal编程技术网

如何在Scala中修复Fibonacci流

如何在Scala中修复Fibonacci流,scala,stream,fibonacci,Scala,Stream,Fibonacci,我定义了一个返回斐波那契流的函数,如下所示: def fib:Stream[Int] = { Stream.cons(1, Stream.cons(2, (fib zip fib.tail) map {case (x, y) => println("%s + %s".format(x, y)); x + y})) } def fib:流[Int]={ 二、反对意见(1, 二、反对意见(2、, (fib-zip-fib.tail)映射{case(x,y)=>println(

我定义了一个返回斐波那契流的函数,如下所示:

def fib:Stream[Int] = { Stream.cons(1, Stream.cons(2, (fib zip fib.tail) map {case (x, y) => println("%s + %s".format(x, y)); x + y})) } def fib:流[Int]={ 二、反对意见(1, 二、反对意见(2、, (fib-zip-fib.tail)映射{case(x,y)=>println(“%s+%s.”格式(x,y));x+y}) } 这些函数工作正常,但看起来效率很低(参见下面的输出)

scala>fib每打印5次 1. 2. 1 + 2 3. 1 + 2 2 + 3 5. 1 + 2 1 + 2 2 + 3 3 + 5 8.
看起来这个函数从一开始就计算第n个斐波那契数。对吗?你将如何修复它

这是因为您使用了
def
。尝试使用
val

lazy val fib: Stream[Int] 
  = 1 #:: 2 #:: (fib zip fib.tail map { case (x, y) => x + y })
基本上,
def
是一种方法;在您的示例中,您每次都在调用该方法,并且每次该方法调用构造一个新流。
def
val
之间的区别已经存在,因此我在这里不再详细介绍。如果您有Java背景,应该非常清楚


这是scala的另一个优点;在Java中,方法可能是递归的,但类型和值可能不是。在scala中,值和类型都可以是递归的。

您可以用另一种方式:

lazy val fibs = {
  def f(a: Int, b: Int): Stream[Int] = a #:: f(b, a + b)
  f(0, 1)
}

惰性val fibs={
def(a:Int,b:Int):流[Int]=a#:::f(b,a+b)
f(0,1)
}

谢谢。但有趣的是,无论如何,如何编写一个函数来返回斐波那契流呢;但每次都返回一个不同的流实例。因为scala有副作用,所以运行时不能用一个延迟计算的valueOk替换表达式。如果我需要一个带参数的函数:例如
fib(f1:Int,f2:Int):Stream[Int]
,其中
f1
f2
是序列的第一个和第二个数字,该怎么办?Scala不是一种引用透明的语言。运行时不会“缓存”对方法的调用。如果您不想每次都构造一个新的流,可以将结果存储起来,或者在本地提取到val中。您如何看待下面的响应中的
def fib(f1:Int,f2:Int):stream[Int]=stream.cons(f1,fib(f1,f1+f2))
?它看起来很有效。外面的应该是def。然后,您可以对返回的流进行精确控制,并能够在需要时删除该引用。例如,如果您只想要一个以第100000个fib编号开始的流,那么您可以执行
val bigs=fibs drop 100000 take n
,而bigs不会在内存中保留前100000个。

lazy val fibs = {
  def f(a: Int, b: Int): Stream[Int] = a #:: f(b, a + b)
  f(0, 1)
}