理解,Ruby中的递归

理解,Ruby中的递归,ruby,recursion,factorial,Ruby,Recursion,Factorial,在递归中,方法调用自身。当有返回值时,我不会跟踪它。例如,在Chris Pine的《学会编程》一书中,有一个关于阶乘的例子 def factorial num if num < 0 return 'You cant\'t take the factorial of a negative number!' end if num <= 1 1 else num * factorial(num-1) end end 并且应该返回6,因为3

在递归中,方法调用自身。当有返回值时,我不会跟踪它。例如,在Chris Pine的《学会编程》一书中,有一个关于阶乘的例子

def factorial num 
  if num < 0
    return 'You cant\'t take the factorial of a negative number!'
  end
  if num <= 1
    1
  else 
    num * factorial(num-1)
  end
end 
并且应该返回
6
,因为
3*2=6
factorial(3-1)
调用递归中传递
2
factorial
方法
num=2
,因此
2*阶乘(2-1)
2*1=2

我们第一次运行代码时得到的
6
会发生什么变化?既然
num=1
,看起来它现在将返回
1
,并转到代码的末尾。但是根据我的理解,我们仍然有前面递归中的
6
2
。这个假设正确吗,因为我们在乘以
num
时调用了阶乘函数?有人能帮我更好地理解这一点吗?假设我们称之为factorial(10),这是如何实现的

现在,我们在第一次运行时得到的6发生了什么 密码

第一轮没有6个;6只出现在最后

情况就是这样:

factorial(3) → 3 * factorial(2)
factorial(3) → 3 * 2 * factorial(1)
factorial(3) → 3 * 2 * 1
函数中没有以前调用的“内存”,每次调用factorial()时,它就像一个全新的函数;当编写为多个函数时是否更清晰

def factorialof3
  3 * factorialof2
end

def factorialof2
  2 * factorialof1
end

def factorialof1
  1
end
现在,我们在第一次运行时得到的6发生了什么 密码

第一轮没有6个;6只出现在最后

情况就是这样:

factorial(3) → 3 * factorial(2)
factorial(3) → 3 * 2 * factorial(1)
factorial(3) → 3 * 2 * 1
函数中没有以前调用的“内存”,每次调用factorial()时,它就像一个全新的函数;当编写为多个函数时是否更清晰

def factorialof3
  3 * factorialof2
end

def factorialof2
  2 * factorialof1
end

def factorialof1
  1
end

Patrice answer将其分解为不同的函数是很好的,如果你有计算机科学方面的背景,那么思考一下什么样的数据结构可能在这里起作用,主要是

因此,当您调用
factorial(3)
时,它将转到
else
块,并在另一次调用factorial(2)时“堆叠”

然后调用
factorial(1)
堆叠另一个

此时,由于
num=1
,(递归必须始终具有基本情况)阶乘(1)将返回1

然后,由于堆栈,最后一个进入是第一个退出,因此阶乘(1)将返回1,这将“下降”到
factorial(2)
调用,因为它是在else块中调用的,对
factorial(2-1)
的调用现在将替换为1,得到2*1,我想现在你明白了


同样重要的是要注意,这个例子试图教你一般的递归,而这个例子并不是真正地道的ruby。作为评论发布的解决方案更像是这样。

Patrice answer将其拆分为单独的函数是好的,如果你有计算机科学方面的背景,它也将有助于思考什么样的数据结构可能在这里起作用,主要是

因此,当您调用
factorial(3)
时,它将转到
else
块,并在另一次调用factorial(2)时“堆叠”

然后调用
factorial(1)
堆叠另一个

此时,由于
num=1
,(递归必须始终具有基本情况)阶乘(1)将返回1

然后,由于堆栈,最后一个进入是第一个退出,因此阶乘(1)将返回1,这将“下降”到
factorial(2)
调用,因为它是在else块中调用的,对
factorial(2-1)
的调用现在将替换为1,得到2*1,我想现在你明白了


同样重要的是要注意,这个例子试图教你一般的递归,而这个例子并不是真正地道的ruby。作为注释发布的解决方案更像它。

首先,您应该将
返回的'blabla'
替换为
raise'blabla'
,因为您的函数返回的是数字,而不是字符串

那就这样看吧

factorial(3)
  3 * factorial(2)
        2 * factorial(1)
              1  # no more recursion, let's go up replacing 
                 # the function calls by the returned value
            end
      end
end
# ↓
factorial(3)
  3 * factorial(2)
        2 * 1  # let's go up again !
      end
end
# ↓
factorial(3)
  3 * 2 # finally
end
# ↓
6

首先,您应该用
raise'blabla'
替换
return'blabla'
,因为您的函数返回的是数字,而不是字符串

那就这样看吧

factorial(3)
  3 * factorial(2)
        2 * factorial(1)
              1  # no more recursion, let's go up replacing 
                 # the function calls by the returned value
            end
      end
end
# ↓
factorial(3)
  3 * factorial(2)
        2 * 1  # let's go up again !
      end
end
# ↓
factorial(3)
  3 * 2 # finally
end
# ↓
6

你看过《盗梦空间》吗?所有的代码。。。当你所要做的就是:
def fact(n)(1..n).inject(1){r,i{r*i}end
:)阶乘函数总是被用作递归的一个例子,当它是解决这个问题的一个糟糕的方法时。我认为这已经对刚开始的程序员造成了各种各样的大脑损伤,一旦每个问题都变成了需要用递归而不是像堆栈这样的适当技术来解决的东西。你看过《盗梦空间》吗?所有那些代码。。。当你所要做的就是:
def fact(n)(1..n).inject(1){r,i{r*i}end
:)阶乘函数总是被用作递归的一个例子,当它是解决这个问题的一个糟糕的方法时。我认为这对初学编程的人造成了各种各样的大脑损伤,一旦每个问题都变成了需要用递归而不是像堆栈这样的适当技术来解决的东西。