R中的语义错误,使用递归

时间:2015-12-23 15:55:35

标签: r recursion fibonacci

我正在R中编写一个短程序,它根据两个起始编号和一个停止编号生成一个Fibonacci序列。我决定使用递归而不是for循环来挑战自己并学习更多东西。但是,我需要生成一个包含我生成的序列的每个数字的向量。我在程序的开头创建了一个空向量来容纳序列。问题是,由于程序是递归的,每次调用函数时该向量都会被重置为空。我希望互联网有一些关于如何继续使用递归的想法,但不能重置为空向量。

代码:

rec <- function (startN1, startN2, stopN2){ 
  #the Fibonacci sequence is generate by starting with two numbers, adding      them to generate a third.
#   To continue generating numbers, you add the previous two values.  Like     so: 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
#   
#   startN1 is the first number you add, startN2 is the second, and stopN2    is the number before which you stop counting.

  fibVals <-vector(mode = "numeric", length = 0)  #fibVals is the vector of     Fibonacci sequence numbers
  if (startN2 < stopN2) { #checks to make sure the stop number has not been exceeded.
    s <- sum(startN1, startN2)  #generates the next number in the sequence
    fibVals <- append(fibVals, s)  #appends the new number to the Fibonacci     Sequence vector
    rec(startN2, s, stopN2)       #recursive call
  } #end if statement
  else{
    print(fibVals)            #prints the Fibonnaci sequence the code (should) generate
}#end else statement
} #end function

2 个答案:

答案 0 :(得分:1)

您可以在fibVals的定义中定义rec向量,并将fibVals的当前值传递给下一个递归调用,例如:

rec <- function (startN1, startN2, stopN2, fibVals=vector(mode = "numeric", length = 0)){ 
    #the Fibonacci sequence is generate by starting with two numbers, adding      them to generate a third.
    #   To continue generating numbers, you add the previous two values.  Like     so: 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
    #   
    #   startN1 is the first number you add, startN2 is the second, and stopN2    is the number before which you stop counting.

    #fibVals <-vector(mode = "numeric", length = 0)  #fibVals is the vector of     Fibonacci sequence numbers
    if (startN2 < stopN2) { #checks to make sure the stop number has not been exceeded.
        s <- sum(startN1, startN2)  #generates the next number in the sequence
        fibVals <- append(fibVals, s)  #appends the new number to the Fibonacci     Sequence vector
        rec(startN2, s,stopN2,fibVals=fibVals)       #recursive call
    } #end if statement
    else{
        print(fibVals)            #prints the Fibonnaci sequence the code (should) generate
    }#end else statement
} #end function

> rec(1,1,100)
 [1]   2   3   5   8  13  21  34  55  89 144

您的方法更紧凑的版本:

rec2 <- function(fibs,stopN2) {
    n <- length(fibs)
    if (fibs[n] < stopN2) {
        next.n <- sum(fibs[(n-1):n])
        rec2(append(fibs,next.n), stopN2=stopN2)
    } else
        fibs
}

> rec2(c(1,1),100)
 [1]   1   1   2   3   5   8  13  21  34  55  89 144

答案 1 :(得分:0)

您可以在函数外部创建空向量,并在函数中使用全局赋值<<-。如果在fibVals函数的环境中找不到rec,它将查找父环境。通过使用全局赋值<<-,您可以在函数中更改fibVals - 我不会习惯使用<<-,因为它有时会让您感到困惑。

fibVals <-vector(mode = "numeric", length = 0)  #fibVals is the vector of     Fibonacci sequence numbers

rec <- function (startN1, startN2, stopN2){ 
  #the Fibonacci sequence is generate by starting with two numbers, adding      them to generate a third.
  #   To continue generating numbers, you add the previous two values.  Like     so: 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
  #   
  #   startN1 is the first number you add, startN2 is the second, and stopN2    is the number before which you stop counting.

  if (startN2 < stopN2) { #checks to make sure the stop number has not been exceeded.
    s <- sum(startN1, startN2)  #generates the next number in the sequence
    fibVals <<- append(fibVals, s)  #appends the new number to the Fibonacci     Sequence vector
    rec(startN2, s, stopN2)       #recursive call
  } #end if statement
  else{
    print(fibVals)            #prints the Fibonnaci sequence the code (should) generate
  }#end else statement
} #end function

rec(1,1,100)
# [1]   2   3   5   8  13  21  34  55  89 144

fibVals
# [1]   2   3   5   8  13  21  34  55  89 144