我试图根据条件对斐波纳契数进行求和。让我们说我有我的功能:
def findingSum(lower: Int, upper: Int): Int{}
传递2个数字。如果我通过findingSum(20 , 90)
,我的函数应该找到这些数字之间的斐波纳契数的总和,换句话说,我应该得到21 + 34 + 55 + 89的总和。
代码:
def findingSum(lower: Int, upper: Int): Int = {
var sum=0;
var current
var prev = 1
var prevprev = 0
for(i <- (n.length-1))
{
current = prev + prevprev;
sum += current;
prevprev = prev;
prev = current;
}
println("Result= " + sum);
}
答案 0 :(得分:8)
首先创建斐波纳契流。
def fib: Stream[Int] = 0 #:: fib.scan(1)(_+_)
然后你拿走,放下并总结。 (或者贬低,接受和总结。无论哪种方式都有效。)
fib.takeWhile(_ <= upper).dropWhile(_ <= lower).sum
像这样在Stream
中保存斐波那契数字的一个好处是计算被缓存。一旦计算出第10个Fibonacci数(55),就不需要重新计算,这是一个简单的查找,然后获得fib(10)
。
所以,把它放在上下文中:
def findingSum(lower: Int, upper: Int): Int = {
def fib: Stream[Int] = 0 #:: fib.scan(1)(_+_)
fib.takeWhile(_ <= upper).dropWhile(_ <= lower).sum
}
但是这种安排确实消除了我之前提到的很好的缓存,因此在函数之外的某处定义fib
可能是有意义的,这样就不会在每次调用时重新定义它。我可能会选择类似的东西:
def fib: Stream[Int] = 0 #:: fib.scan(1)(_+_)
def findingSum(l: Int, u: Int) = fib.takeWhile(_ <= u).dropWhile(_ <= l).sum
<强> CORRECTION 强>
关于流缓存的信息来自here,其中指出:
... Stream是一个尾巴是懒惰的List。计算后,一个值 保持计算并重复使用。
但是,稍后在同一页面上,它也会对Streams说:
...主要好处是编写无限序列(特别是序列 递归定义)。人们可以避免保留所有的流 但是,通过确保你不保留对其头部的引用来记忆 (例如,通过使用def而不是val来定义Stream)。
因此,虽然我对Stream
缓存没有错,但我的代码示例却未能真正利用它。
将def fib: Stream...//etc.
替换为lazy val fib: Stream...//etc.
,我认为我们很好。
答案 1 :(得分:2)
def findingSum(lower: Int, upper: Int): Int = {
(lower to upper).filter(isFibonacci).sum
}
你去了,(我假设你有这种方法来验证数字是否是范围内的斐波纳契数)