Recursion 生成递归和结构递归之间的区别是什么?

Recursion 生成递归和结构递归之间的区别是什么?,recursion,functional-programming,scheme,racket,Recursion,Functional Programming,Scheme,Racket,Racket中的生成递归和结构递归有什么区别?当“子问题”与可能的数据片段完全匹配时,就会发生结构递归 (define (solve-problem prob) (cond ;; trivial case [(trival-problem? prob) (... prob ...)] [else ; combine the solutions (... ; solve the first sub-problem (solve

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

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

(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
      ...)]))
例如,处理列表
lox
。当
lox
为空时,情况就很简单了。否则,第一个子问题处理
(第一个lox)
,第二个子问题处理
(其余lox)
。通过调用helper函数来解决每个子问题,并将解决方案组合在一起

(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
      ...)]))

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

请参阅或感谢。这个例子是生成递归吗?不,答案中的代码使用结构递归加上累加器。这很难看到,因为有多个输入正在一起处理。每个“子问题”都是直接来自数据定义的一部分,而不是来自生成思想的其他部分。有趣的是,我没有看到递归以这种方式区分。你会认为流是生成递归的形式吗?自然的递归调用实际上并不针对数据的子部分,而是针对由数据生成的其他内容。然而,它仍然比大多数生成式递归更容易设计,因为数据仍然告诉您子问题是什么。