使用map(v,reduce)在R中创建斐波那契序列?

问题描述 投票:2回答:1

我想知道我们是否可以使用 purrr's mapreduce 创建类似于这个JavaScript的斐波那契函数。

function fib(n){
  return new Array(n).fill(1).reduce((arr, _ ,i) => {
    arr.push((i <= 1) ? i : arr[i-2] + arr[i-1])
    return arr
  },[]) ;
}
console.log(fib(10))

我在这里看到了答案 R中的斐波那契序列。 但我想知道我们是否可以特别使用purrr的 reduce 如果是,怎么做?

r purrr
1个回答
5
投票

我想 purrr::accumulate() 是比较适合的任务。

n <- 10                                         # Desired number of values
purrr::accumulate( .init = c(0L,1L),            # Starting with (0,1)
                   rep(0,n),                    # Accumulate n times
                   ~c(.x,sum(.x))[2:3]          # (x,y) -> (x, y, x+y)[2:3]
                 ) %>% 
    purrr::map_int( `[`, 1 )                    # (x,y) -> x

# [1]  0  1  1  2  3  5  8 13 21 34 55

这个解决方案的关键是在整个过程中保持成对的数值。accumulate() 呼叫。(0,1), (1,1), (1,2)等,因为你需要两个以前的值来计算新的值。

之后是检索每对的第一个元素。


3
投票

这种方法如何与 map?

n<-10
map(n,function(x) round(((5+sqrt(5))/10) * ((1+sqrt(5))/2) ** (1:x-1)))
[[1]]
 [1]  1  1  2  3  5  8 13 21 34 55

灵感来自于 本回答. 显然,@Artem的回答更符合问题的精神。所以向他们致敬。


2
投票

下面是一个使用reduce的解决方案

fib <- function(n) reduce(rep(0,n-1), .f=function(x,y) c(x, x[length(x)-1] + x[length(x)]), .init=c(0,1))

fib(10)
# [1]  0  1  1  2  3  5  8 13 21 34 55

这个解决方案的好处是,它非常容易解释。基本上你只需要用最基本的还原功能,按照函数的定义把斐波那契数写在函数里就可以了,没什么花哨的。

© www.soinside.com 2019 - 2024. All rights reserved.