我正在尝试将我的Pascal三角形生成器的实现作为一个Ruby学习实验。我有以下可用的代码:
module PascalMemo
@cache = {}
def PascalMemo::get(r,c)
if @cache[[r,c]].nil? then
if c == 0 || c == r then
@cache[[r,c]] = 1
else
@cache[[r,c]] = PascalMemo::get(r - 1, c) + PascalMemo::get(r - 1, c - 1)
end
end
@cache[[r,c]]
end
end
def pascal_memo (r,c)
PascalMemo::get(r,c)
end
这能说得更简洁些吗?具体地说,我能用比这更简单的局部闭包创建一个全局作用域函数吗?
发布于 2012-11-06 06:02:07
def pascal_memo
cache = [[1]]
get = lambda { |r, c|
( cache[r] or cache[r] = [1] + [nil] * (r - 1) + [1] )[c] or
cache[r][c] = get.(r - 1, c) + get.(r - 1, c - 1)
}
end
p = pascal_memo
p.( 10, 7 ) #=> 120
请注意,上面的构造确实实现了内存化,它不仅仅是一个简单的递归方法。
发布于 2012-11-06 05:38:21
可以说得更简洁些吗?
这似乎很清楚,IMO,module
ing通常是一个很好的直觉。
我能用比这更简单的局部闭包创建全局作用域的函数吗?
另一种选择是递归lambda
memo = {}
pascal_memo = lambda do |r, c|
if memo[[r,c]].nil?
if c == 0 || c == r
memo[[r,c]] = 1
else
memo[[r,c]] = pascal_memo[r - 1, c] + pascal_memo[r - 1, c - 1]
end
end
memo[[r,c]]
end
pascal_memo[10, 2]
# => 45
发布于 2012-11-08 00:24:58
我已经找到了一种更令人满意的方法来完成我想要的东西,因为它产生的是一个函数而不是一个lambda:
class << self
cache = {}
define_method :pascal_memo do |r,c|
cache[[r,c]] or
(if c == 0 or c == r then cache[[r,c]] = 1 else nil end) or
cache[[r,c]] = pascal_memo(r-1,c) + pascal_memo(r-1,c-1)
end
end
这将打开主对象的元类/单例类,然后使用define_method添加一个关闭缓存变量的新方法,该变量将超出除pascal_memo方法之外的所有对象的作用域。
https://stackoverflow.com/questions/13244879
复制相似问题