【发布时间】:2011-10-26 15:09:33
【问题描述】:
我有以下代码可以正确生成大小为num 的所有可能的树:
class Tree
attr_accessor :left, :right
def initialize left = nil, right = nil
@left = left
@right = right
end
# Don't ever specify any arguments, it will make me very angry.
# Tilt your head 90 degrees to the side to see the tree when viewing.
def print level = 0
@right.pretty_print(level + 1) if @right
puts (' ' * level) + to_s
@left.pretty_print(level + 1) if @left
end
def self.generate num
trees = []
generate_subtrees(num) { |tree| trees << tree } if num > 0
trees
end
private
def self.generate_subtrees num, &block
if num == 0
yield nil
else
(1..num).each do |root_position|
generate_subtrees(root_position - 1) do |left|
generate_subtrees(num - root_position) do |right|
yield Tree.new nil, left, right
end
end
end
end
end
end
我正在尝试(为此)将其“浓缩”为一种方法,利用 lambda 递归。我目前的尝试(几次迭代)如下:
def self.generate num
trees = []
gen = ->(num, &block) do
if num == 0
yield nil # L61
else
(1..num).each do |root_position| # L63
gen.call(root_position - 1) do |left| # L64
gen.call(num - root_position) do |right|
block.call { Tree.new nil, left, right }
end
end
end
end
end
gen.call(num) { |tree| trees << tree } # L73
trees
end
这会导致错误(上面提到的引用行):
LocalJumpError: no block given (yield)
from tree.rb:61:in `block in generate'
from tree.rb:64:in `call'
from tree.rb:64:in `block (2 levels) in generate'
from tree.rb:63:in `each'
from tree.rb:63:in `block in generate'
from tree.rb:73:in `call'
from tree.rb:73:in `generate'
from (irb):4
from /Users/amarshall/.rbenv/versions/1.9.2-p290/bin/irb:12:in `<main>'
我做错了什么?这个主要是学术问题的替代解决方案也受到欢迎。
【问题讨论】:
-
感谢戴夫的编辑!永远无法完全正确地拼写 lambdas……
-
你应该为 Tree 类发布一些最少的代码,这样我们就可以轻松地测试这个函数的新版本。
-
@DavidGrayson 我已按要求发布了更多 Tree 类(虽然不是全部,但如果我的最小化有任何错误,请告诉我)。