斐波那契函数

4
我们被分配了一个任务,但我们无法理解:
编写一个R函数,该函数将生成一个向量,其中包含斐波那契数列的前n个项。具体步骤如下: (a)创建向量以存储结果。 (b)初始化前两个元素。 (c)运行循环,i从3到n,填充第i个元素。
目前的工作进展:
vast=function(n){
 vast=vector()
 vast[1]=1
 vast[2]=1
 for(i in 3){vast[i]=vast[i-1]+vast[i-2]}
 }

我们最终遇到的错误是:对象类型 'closure' 无法进行子集操作?
我们应该如何生成所需的函数?

1
  1. 给你的向量取一个与函数不同的名称。
  2. 在创建向量时,确保它是正确的类型和大小:fib = numeric(n)
- Roland
1
初始化 vast <- rep(NA, n) 并正确循环 for (i in 3:n) - Richard Herron
关于你的第二个问题,我有一个提示:谷歌。只需要5秒钟,它就给了我几个不同的选项。 - Mikko
2
如果你想惹恼你的老师,可以使用闭合形式 ;)(通常他们会用斐波那契示例来教递归)。 - bdecaf
1
如果你在StackOverflow上得到了帮助,请告诉你的老师,我会给你无限的加分。 - Ben Bolker
显示剩余2条评论
1个回答

7

我赞成@bdecaf提出的闭合形式(因为这会让你的老师很生气):

vast = function(n) round(((5 + sqrt(5)) / 10) * (( 1 + sqrt(5)) / 2) ** (1:n - 1))

但是你可以通过两个小改变来修复你已有的代码:
vast=function(n){
 vast=vector()
 vast[1]=1
 vast[2]=1
 for(i in 3:n){vast[i]=vast[i-1]+vast[i-2]}
 return(vast)
 }

我仍然会遵循之前给出的建议,特别是使用不同的名称来命名你的向量和函数,但事实上有很多不同的方法可以达到你的目标。 首先,在这种情况下根本没有必要初始化一个空向量,因为我们可以在R中使用for循环来像你已经做的那样扩展向量。例如,你可以这样做:

vast=function(n){
  x = c(1,1)
  for(i in 3:n) x[i] = x[i-1] + x[i-2]
  return(x)
}

当然,我们对编程还有很多东西要学习,但这也是我们在这里的原因。我们在某个时候都得到过他人的帮助,随着我们帮助别人提高,我们自己也会变得更好。
更新:正如@Carl Witthoft指出的,最佳实践是在已知大小时将向量初始化为适当的大小,以节省时间和空间,因此完成此任务的另一种方法是:
vast=function(n) {
  x = numeric(n)
  x[1:2] = c(1,1)
  for(i in 3:n) x[i] = x[i-1] + x[i-2]
  return(x)
}

1
一般来说,最好预先分配整个向量。这不仅可以节省时间(因为每次循环都扩展向量是很多操作),还可以节省空间(因为向量在扩展时会进行内部复制)。 - Carl Witthoft
1
@CarlWitthoft 您说得很对,我认为人们应该尽早学习最佳实践。我的观点是,有不同的方法可以奏效,而对于斐波那契数列,很少有人会对生成足够大的序列感兴趣,以至于空间和时间的节省会产生实际上有意义的差异,但我会更新以突出最佳实践。 - Sam Dickson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接