ruby 什么是递归,它是如何工作的?

g2ieeal7  于 2023-01-25  发布在  Ruby
关注(0)|答案(5)|浏览(189)

有没有人能解释一下递归到底是什么(以及它在Ruby中是如何工作的,如果这不是太多的要求的话)。我遇到了一个依赖于递归的冗长代码片段,它让我很困惑(我现在把它弄丢了,它不完全相关)。

06odsfpq

06odsfpq1#

递归函数/方法调用自身。对于递归算法的终止,你需要一个基本情况(例如,函数不递归调用自身的条件),并且你还需要确保在每次递归调用时都更接近基本情况。让我们看一个非常简单的例子:

def countdown(n)
  return if n.zero? # base case
  puts n
  countdown(n-1)    # getting closer to base case 
end               

countdown(5)
5
4
3
2
1

有些问题可以用递归很优美地表达出来,例如许多数学函数都是用递归的方法来描述的。

balp4ylt

balp4ylt2#

要理解递归,首先需要理解递归。
现在,严肃地说,递归函数是一个调用自身的函数,这种构造的一个经典例子是斐波那契数列:

def fib(n)
  return n if (0..1).include? n
  fib(n-1) + fib(n-2) if n > 1
end

使用递归函数给你带来了强大的能力,但也带来了很大的响应性(双关语),并且存在一些风险。例如,如果你的递归性太大,你可能会以堆栈溢出结束(我很幸运):-)

aelbi1ox

aelbi1ox3#

Ruby on Rails示例:

递归将生成父数组父

a/m/文件.rb

class Document < ActiveRecord::Base

  belongs_to :parent, class_name: 'Document'

  def self.get_ancestors(who)
    @tree ||= []
    # @tree is instance variable of Document class object not document instance object
    # so: Document.get_instance_variable('@tree')

    if who.parent.nil?
      return @tree
    else
      @tree << who.parent
      get_ancestors(who.parent)
    end
  end

  def ancestors
    @ancestors ||= Document.get_ancestors(self)
  end

end

控制台

d = Document.last
d.ancestors.collect(&:id)
# => [570, 569, 568]

https://gist.github.com/equivalent/5063770

cig3rfwq

cig3rfwq4#

通常递归是关于方法调用自身的,但是你可能遇到的是递归结构,也就是对象引用自身,Ruby 1.9处理得非常好:

h = {foo: 42, bar: 666}
parent = {child: {foo: 42, bar: 666}}
h[:parent] = parent
h.inspect # => {:foo=>42, :bar=>666, :parent=>{:child=>{...}}}

x = []
y = [x]
x << y
x.inspect # => [[[...]]]
x == [x]  # => true

我觉得最后一行很恶毒几年前,我在比较递归结构时讨论过这类问题。

wko9yo5t

wko9yo5t5#

我只是想补充一下,每个递归算法都由两部分组成:
1.基本情况
1.递归情况
基本情况是告诉你的算法中断,这样它就不会继续无限或你的内存耗尽。
递归case是确保调用它自己,但要削减或缩减调用它所用的参数的部分。

相关问题