我试图编写一个函数来计算R中的第n个斐波那契数。我可以递归地做到这一点。
fibonacci = function(n){
if (n == 1) {return(1)}
if (n == 2) {return(2)}
return(fibonacci(n - 1) + fibonacci(n - 2))
}
我在R中找不到任何示例,但是从其他语言的指南中,我想到了以下内容。但是,它似乎并没有运行得更快。
fibonacci = function(n, lookup = NULL){
if (is.null(lookup)) {
lookup = integer(n + 1)
}
if (n == 1) {return(1)}
if (n == 2) {return(2)}
lookup[1] = 1
lookup[2] = 2
if (lookup[n - 1] == 0) {
lookup[n - 1] = fibonacci(n - 1, lookup)
}
if (lookup[n - 2] == 0) {
lookup[n - 2] = fibonacci(n - 2, lookup)
}
return(lookup[n - 1] + lookup[n - 2])
}
答案 0 :(得分:4)
解决方案的问题是您的查找向量始终在调用框架环境中,并且新的解决方案不会传播到调用者,即,当函数返回时,对查找向量的更改会丢失。为了使持久变量成为C中的静态变量,您可以为充当备忘录的函数创建一个属性。这是一种解决方案:
fibonaccid = function(n, init=T){
if (init) {
lookup <- integer(n + 1)
lookup[1] <- 1
lookup[2] <- 2
} else {
lookup <- attr(fibonaccid, ".lookup")
}
# ... calculate lookup as before, recurse with fibonaccid(...,init=F)
attr(fibonaccid, ".lookup") <<- lookup
return(lookup[n - 1] + lookup[n - 2])
}
运行速度确实更快:
R> system.time(print(fibonacci(35)))
[1] 14930352
user system elapsed
20.923 0.140 21.446
R> system.time(print(fibonaccid(35)))
[1] 14930352
user system elapsed
0.202 0.006 0.209
有关更多信息,请参见this post。