【问题标题】:stack level too deep (SystemStackError) when recursing递归时堆栈级别太深(SystemStackError)
【发布时间】:2017-05-03 21:43:25
【问题描述】:

我想做这个简单的计算,但它抱怨堆栈不够深,即使对于 n 的非常小的数字,例如 4。类似主题的其他 SO 帖子建议使用尾递归,但这不适用在这里,因为您只在达到基本情况时才添加累积值。

RubyVM::InstructionSequence.compile_option = {
:tailcall_optimization => true,
:trace_instruction => false
}

def recursively_count_paths(x , y, n)
 if x == n &&  y == n
  return 1
  puts " we got a path people"
 elif x == n
  puts "x is done"
  return recursively_count_paths(x, y + 1, n)
 elif y == n
  puts "y is done"
  return recursively_count_paths(x + 1, y, n)
 else
 return (recursively_count_paths(x + 1, y, n) + 
recursively_count_paths(x, y + 1, n))
 end  
end

recursively_count_paths(0, 0, 20)

在其他情况下我不应该返回吗?

【问题讨论】:

  • puts 永远不会在第一个 if 条件下执行
  • @Ruslan 是真的。但这与问题是正交的。
  • elsif 而不是 elif?我没有在 RubyVM 上运行它,所以我不确定这会有所不同
  • @MickeySheu 是的!
  • 如果你在进行寻路,有许多算法被证明是有效的,而且不会超出你的堆栈限制。我认为你使用的这个重复了很多工作,也很浪费。

标签: ruby


【解决方案1】:

在这种情况下,尾递归不相关。由于您多次递归调用该方法,编译器无法进行该优化。大多数电话都是不必要的。我能够将您的代码重写为:

def recursively_count_paths(x, y, n)
  return 0 if x > n or y > n
  return 1 if x == n &&  y == n
  return recursively_count_paths(x+1, y, n) + recursively_count_paths(x, y+1, n)
end

第一行查找超出范围的路径并且不计算这些路径。第二行相当于您的第一个if 语句。如果路径已完成,则返回 1。最后一行与您的最终return 语句相同,只是将所有向北的路径与向东的所有路径相加。由于我们两次调用recursively_count_paths,尾调用优化仍然无济于事。

如果您使用 n=20 运行它,您可能会注意到它需要一段时间。这是因为随着网格大小的增加,该算法所需的时间呈指数增长。那是因为你一遍又一遍地计算相同的子路径。也是 Project Euler Problem 15,所以我不会在这里提供我的解决方案。不过,我会给你一个提示:保存你的工作。

【讨论】:

  • 是的,我正在解决这个问题。我记得那和帕斯卡的三角形之间有关系,我最终设计了一个 O(n^2) 解决方案,感谢上帝!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-10
  • 2013-10-05
  • 2014-10-25
  • 2017-08-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多