我有以下代码正确生成所有可能的大小为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>'
我做错了什么?这个主要是学术问题的替代解决方案也是受欢迎的。
答案 0 :(得分:3)
yield
关键字在lambda中不起作用。另一种方法是使用&block
,就像你在第64和65行所做的那样:
gen = ->(num, &block) do
if num == 0
block.call(nil)
else
# ...
end
gen.call(num) { |tree| trees << tree }