理解递归的最佳方法是在代码中添加一些 put 语句,并在视觉上分隔方法的每个实例。这可以在这里完成,如下所示。
INDENT = 6
def indent; $col += INDENT; end
def undent; $col -= INDENT; end
def pu(s); puts "#{" "*$col}#{s}"; end
def puhline; pu('-'*(65-$col)); end
def recurse(first, *rest)
indent
puhline
pu "recurse called with arguments first = #{first}, rest = #{rest}"
if rest.empty?
c = [[first], rest]
pu "returning #{c}"
puhline
undent
return c
end
pu "calling recurse(#{rest})"
a = recurse(*rest)
pu "#{a} is returned"
b = a.flat_map { |a| [a, [first] + a] }
pu "returning a.flat_map { |a| [a, [#{first}] + a] } = #{b}"
puhline
undent
b
end
$col = -INDENT
recurse(1,2,3,4)
显示以下内容。请注意,该方法的每个实例执行的计算在下面垂直对齐。
-----------------------------------------------------------------
recurse called with arguments first = 1, rest = [2, 3, 4]
calling recurse([2, 3, 4])
-----------------------------------------------------------
recurse called with arguments first = 2, rest = [3, 4]
calling recurse([3, 4])
-----------------------------------------------------
recurse called with arguments first = 3, rest = [4]
calling recurse([4])
-----------------------------------------------
recurse called with arguments first = 4, rest = []
returning [[4], []]
-----------------------------------------------
a = [[4], []] is returned
returning a.flat_map { |a| [a, [3] + a] } = [[4], [3, 4], [], [3]]
-----------------------------------------------------
a = [[4], [3, 4], [], [3]] is returned
returning a.flat_map { |a| [a, [2] + a] } = [[4], [2, 4], [3, 4], [2, 3, 4], [], [2], [3], [2, 3]]
-----------------------------------------------------------
a = [[4], [2, 4], [3, 4], [2, 3, 4], [], [2], [3], [2, 3]] is returned
returning a.flat_map { |a| [a, [1] + a] } = [[4], [1, 4], [2, 4], [1, 2, 4], [3, 4], [1, 3, 4], [2, 3, 4], [1, 2, 3, 4], [], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
-----------------------------------------------------------------
You can do that as follows.
def recurse(first, *rest)
return [[first], rest] if rest.empty?
recurse(*rest).flat_map { |a| [a, [first] + a] }
end
The best way to understand recursion is to add some puts statements to the code and to visually separate each instance of the method. That could be done here as follows.
INDENT = 6
def indent; $col += INDENT; end
def undent; $col -= INDENT; end
def pu(s); puts "#{" "*$col}#{s}"; end
def puhline; pu('-'*(65-$col)); end
def recurse(first, *rest)
indent
puhline
pu "recurse called with arguments first = #{first}, rest = #{rest}"
if rest.empty?
c = [[first], rest]
pu "returning #{c}"
puhline
undent
return c
end
pu "calling recurse(#{rest})"
a = recurse(*rest)
pu "#{a} is returned"
b = a.flat_map { |a| [a, [first] + a] }
pu "returning a.flat_map { |a| [a, [#{first}] + a] } = #{b}"
puhline
undent
b
end
$col = -INDENT
recurse(1,2,3,4)
The following is displayed. Note that calculations performed by each instance of the method are vertically aligned below.
-----------------------------------------------------------------
recurse called with arguments first = 1, rest = [2, 3, 4]
calling recurse([2, 3, 4])
-----------------------------------------------------------
recurse called with arguments first = 2, rest = [3, 4]
calling recurse([3, 4])
-----------------------------------------------------
recurse called with arguments first = 3, rest = [4]
calling recurse([4])
-----------------------------------------------
recurse called with arguments first = 4, rest = []
returning [[4], []]
-----------------------------------------------
a = [[4], []] is returned
returning a.flat_map { |a| [a, [3] + a] } = [[4], [3, 4], [], [3]]
-----------------------------------------------------
a = [[4], [3, 4], [], [3]] is returned
returning a.flat_map { |a| [a, [2] + a] } = [[4], [2, 4], [3, 4], [2, 3, 4], [], [2], [3], [2, 3]]
-----------------------------------------------------------
a = [[4], [2, 4], [3, 4], [2, 3, 4], [], [2], [3], [2, 3]] is returned
returning a.flat_map { |a| [a, [1] + a] } = [[4], [1, 4], [2, 4], [1, 2, 4], [3, 4], [1, 3, 4], [2, 3, 4], [1, 2, 3, 4], [], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
-----------------------------------------------------------------
发布评论
评论(1)
您可以按如下方式进行操作。
请参阅Enumerable#flat_map。
理解递归的最佳方法是在代码中添加一些 put 语句,并在视觉上分隔方法的每个实例。这可以在这里完成,如下所示。
显示以下内容。请注意,该方法的每个实例执行的计算在下面垂直对齐。
You can do that as follows.
See Enumerable#flat_map.
The best way to understand recursion is to add some puts statements to the code and to visually separate each instance of the method. That could be done here as follows.
The following is displayed. Note that calculations performed by each instance of the method are vertically aligned below.