2016-02-06 2 views
2

Я пытаюсь вернуть поток первого N Fibonacci с N, указанным в качестве параметра. Так что давайте скажем, если я передам 6 своей функции, я должен получить «0,1,1,2,3,5», или если я прохожу 7, я должен получить «0,1,1,2,3,5,8» и скоро. Любые идеи о том, как это сделать?Как вернуть поток первых чисел N Фибоначчи?

Вот то, что я до сих пор:

def fibonacci(n: Int): Stream[Int] = { 
    if (n == 0) return 0; 
    if (n<= 2) return 1; 

    fibTerm = fibonacci(n - 1) + fibonacci(n - 2); 
    return fibTerm; 
} 
+0

Можете ли вы отметить популярнейший ответ, как правильно? Спасибо – marios

+0

Я только что сделал. Спасибо Марио! – abpre

ответ

3

Создание потока Фибоначчи.

val fib: Stream[Int] = 0 #:: fib.scan(1)(_+_) 

Возьмите n элементы из него.

fib.take(n) 

Вот как вы можете добавить его в функции:

def fibonacci(n: Int): Stream[Int] = { 
    lazy val fib: Stream[Int] = 0 #:: fib.scan(1)(_+_) 
    fib.take(n) 
} 

Обратите внимание, что lazy необходима иначе компилятор запутается и дает: "<> ошибка: опережающая ссылка распространяется на определение of value fib "

+0

Поместите эти две строки в функцию 'fibonacci'. Это все, что вам нужно. Эти две строки и конечная скобка '}', и все готово. – jwvh

+0

Вы уверены? он, похоже, не работает. Вы проверили это? – abpre

+2

Это верно, и это потрясающе. Раньше я думал, что реализация Stream в ScalaDoc была короткой. Бог. – marios

0

Я предпочитаю эту версию, хотя ее медленнее на случай, если вам действительно нужны все номера ;-)

def fibonacci(n: Int): Stream[Int] = { 
    def fib(n:Int) = 
     Math.floor(Math.pow(0.5*(1.0+Math.pow(5,0.5)),n)/Math.pow(5,0.5)+0.5).toInt 
    Stream.range(0,n).map(fib) 
} 
2

Я считаю, что ответы от @dth и @jwvh велики. Просто для полноты здесь есть еще одна альтернатива:

def fibonacci(n: Int): Stream[Int] = { 
    def f(a: Int, b: Int): Stream[Int] = a #:: f(b, a + b); 
    f(0,1).take(n) 
} 
+1

Да, это на самом деле то, как вы должны использовать потоки. Я также разместил это решение по почти идентичному вопросу несколько раньше. Я просто хотел указать, что существует прямой способ вычисления чисел Фибоначчи, и ему надоело давать тот же ответ на тот же вопрос ;-) – dth

+0

Рекурсивные определения потоков настолько классные :). спасибо за обмен вашими ответами! – marios

1

Вот еще один:

scala> Stream.iterate((0, 1)){case (a, b) => (b, a + b)}.map(_._1) 
res0: scala.collection.immutable.Stream[Int] = Stream(0, ?) 

scala> res0.take(10).force 
res1: scala.collection.immutable.Stream[Int] = Stream(0, 1, 1, 2, 3, 5, 8, 13, 21, 34) 
Смежные вопросы