【问题标题】:What is the difference between generative and structural recursion?生成递归和结构递归有什么区别?
【发布时间】:2018-05-06 23:30:37
【问题描述】:

Racket 中的生成递归和结构递归有什么区别?

【问题讨论】:

标签: recursion functional-programming scheme racket


【解决方案1】:

当“子问题”与可能的数据片段完全匹配时,就会发生结构递归。

例如,处理列表lox。最简单的情况是lox 为空。否则第一个子问题处理(first lox),第二个子问题处理(rest lox)。您通过调用辅助函数来解决每个子问题,然后组合这些解决方案。

(define (process-list-of-x lox)
  (cond
    ;; trivial case
    [(empty? lox) ...]
    [(cons? lox)
     ; combine the solutions
     (...
      ; solve the first sub-problem
      (process-x (first lox))         ; data-def tells you what the first sub-problem is
      ...
      ; solve the second sub-problem
      (process-list-of-x (rest lox))  ; data-def tells you what the second sub-problem is
      ...)]))

不同的是,结构递归告诉您子问题是什么,而在生成递归中,子问题可以是任何东西。你经常需要一个新的想法来分解它。特定于问题的尤里卡时刻,而不是数据。

(define (solve-problem prob)
  (cond
    ;; trivial case
    [(trival-problem? prob) (... prob ...)]
    [else
     ; combine the solutions
     (...
      ; solve the first sub-problem
      (solve-problem (generate-first-sub-problem prob))   ; you have to figure this out
      ...
      ; solve the second sub-problem
      (solve-problem (generate-second-sub-problem prob))  ; data-def doesn't tell you how
      ...)]))

此外,结构递归保证它会终止,因为子问题来自分解数据。在生成递归中,子问题可能更复杂,因此您需要一些其他方法来确定它是否终止。

【讨论】:

  • 谢谢。 this 示例会是生成递归吗?
  • 不,该答案中的代码使用结构递归和累加器。很难看到,因为有多个输入一起处理。每个“子问题”都是直接来自数据定义的一部分,而不是来自生成想法的其他部分。
  • 有趣——我还没有看到以这种方式区分递归。你会认为流是一种生成递归吗?
  • 排序的。自然递归调用实际上并不是在数据的子片段上,而是在由数据生成的其他东西上。但是,它仍然比大多数生成递归更容易设计,因为数据仍然可以告诉您子问题是什么。
猜你喜欢
  • 2012-12-25
  • 2016-02-01
  • 2013-11-16
  • 1970-01-01
  • 2016-03-26
  • 1970-01-01
  • 1970-01-01
  • 2020-11-01
  • 1970-01-01
相关资源
最近更新 更多