首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >带记忆的Ruby Pascal三角形生成器

带记忆的Ruby Pascal三角形生成器
EN

Stack Overflow用户
提问于 2012-11-06 05:22:58
回答 3查看 392关注 0票数 3

我正在尝试将我的Pascal三角形生成器的实现作为一个Ruby学习实验。我有以下可用的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

这能说得更简洁些吗?具体地说,我能用比这更简单的局部闭包创建一个全局作用域函数吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-11-06 06:02:07

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

请注意,上面的构造确实实现了内存化,它不仅仅是一个简单的递归方法。

票数 2
EN

Stack Overflow用户

发布于 2012-11-06 05:38:21

可以说得更简洁些吗?

这似乎很清楚,IMO,moduleing通常是一个很好的直觉。

我能用比这更简单的局部闭包创建全局作用域的函数吗?

另一种选择是递归lambda

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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
票数 1
EN

Stack Overflow用户

发布于 2012-11-08 00:24:58

我已经找到了一种更令人满意的方法来完成我想要的东西,因为它产生的是一个函数而不是一个lambda:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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方法之外的所有对象的作用域。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13244879

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文