如何在Ruby中编写一个递归阶乘函数?

4

我想请你帮忙翻译如何在 Ruby 中编写递归阶乘函数的方法。以下是我的代码,它是 Lisp 语言的,但我想在 Ruby 中实现相同的功能。

(defun factorial (N)
    (if (= N 1) 1
        (* N (factorial (- N 1)))))

7
https://dev59.com/Mbfna4cB1Zd3GeqPojrz - Fab
我本来想问你为什么链接了我的问题,但后来我意识到了哈哈。太棒了! - Wah.P
@Fab 这是一个完全重复的! - coredump
逻辑错误:0!= 1 - Max
1个回答

7

以下是如何使用 Ruby 编写您的代码:

def factorial(n)
  return 1 if n == 1
  n * factorial(n - 1)
end

factorial(5)
#=> 120
factorial(7)
#=> 5040

根据Stefan的评论进行编辑:

为了避免在n值较大时出现SystemStackError错误,可以使用尾递归方法。同时需要启用Ruby的tailcall优化。

# before edit
factorial(100_000).to_s.size
#=> stack level too deep (SystemStackError)

为了避免出现“SystemStackError”错误,请按照以下步骤操作:
RubyVM::InstructionSequence.compile_option = {
  tailcall_optimization: true,
  trace_instruction: false
}

RubyVM::InstructionSequence.new(<<-CODE).eval
  def factorial(n, acc = 1)
    return acc if n == 1
    factorial(n - 1, n * acc)
  end
CODE

puts factorial(100_000).to_s.size
#=> 456574

资源1 资源2

这两个资源与Ruby中的递归和尾调用优化相关。

2
或者如果您更字面地翻译Lisp代码:n == 1 ? 1 : n * factorial(n - 1),但我个人更喜欢使用保护版本。 - 3limin4t0r
不确定Lisp,但是这个Ruby版本在n的大值下会导致堆栈溢出。您可以将其转换为尾递归方法并启用Ruby的尾调用优化。 - Stefan

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