Recursion 嵌套平方根递归

Recursion 嵌套平方根递归,recursion,scheme,Recursion,Scheme,让我们假设一个函数具有以下数值输出模式 (function 0) = sqrt(6) (function 1) = sqrt(6 + (2 * sqrt(7))) (function 2) = sqrt(6 + (2 * sqrt(7 + (3 * sqrt(8))))) etc... 在方案中,我使用以下递归函数来计算此模式 (define (function depth) (cond ((= depth 0) (sqrt 6)) (else (

让我们假设一个函数具有以下数值输出模式

(function 0) = sqrt(6)

(function 1) = sqrt(6 + (2 * sqrt(7)))

(function 2) = sqrt(6 + (2 * sqrt(7 + (3 * sqrt(8)))))

etc...
在方案中,我使用以下递归函数来计算此模式

(define (function depth)
    (cond
        ((= depth 0) (sqrt 6))
        (else (+ (function (- depth 1)) (* (+ depth 1) (sqrt (+ depth 6)))))
        )
    )

我不知道如何写else,这样平方根就嵌套了。有人能给我一个建议吗?

这个公式执行起来有点棘手,但是使用a应该可以(这只是为了避免创建另一个过程):

如果命名的
let
困扰您,这里有一个完全等效的解决方案,使用嵌套的帮助程序:

(define (function n)
  (let helper ((a 2))
    (if (= (- a 2) n)
        (sqrt (+ a 4))
        (sqrt (+ a 4 (* a (helper (+ a 1))))))))
(define (function n)
  (define (helper a)
    (if (= (- a 2) n)
        (sqrt (+ a 4))
        (sqrt (+ a 4 (* a (helper (+ a 1)))))))
  (helper 2))
(define (helper a n)
  (if (= (- a 2) n)
      (sqrt (+ a 4))
      (sqrt (+ a 4 (* a (helper (+ a 1) n))))))

(define (function n)
  (helper 2 n))
如果嵌套过程也是一个问题,则将辅助对象提取为一个完全独立的过程:

(define (function n)
  (let helper ((a 2))
    (if (= (- a 2) n)
        (sqrt (+ a 4))
        (sqrt (+ a 4 (* a (helper (+ a 1))))))))
(define (function n)
  (define (helper a)
    (if (= (- a 2) n)
        (sqrt (+ a 4))
        (sqrt (+ a 4 (* a (helper (+ a 1)))))))
  (helper 2))
(define (helper a n)
  (if (= (- a 2) n)
      (sqrt (+ a 4))
      (sqrt (+ a 4 (* a (helper (+ a 1) n))))))

(define (function n)
  (helper 2 n))
无论如何,结果与预期一致:

(function 0)
=> 2.449489742783178

(function 1)
=> 3.360283116365224

(function 2)
=> 3.724280930782559

下面是我将如何实现它。与@Oscar的版本相比

  • 它涵盖了n的错误输入值(Oscar的解决方案将无限期地循环负值)
  • 没有多余的表达
  • 代码:

    测试:

    > (for ((i (in-range 10))) (printf "~a ~a\n" i (function i)))
    0 2.449489742783178
    1 3.360283116365224
    2 3.7242809307825593
    3 3.8777446879222386
    4 3.9447403174010236
    5 3.9746786776817733
    6 3.988278318778271
    7 3.994530823306873
    8 3.997431999017166
    9 3.998787961199304
    
    > (function -2)
    n is negative
    

    这是一个很好的解决方案,但我应该补充一点,即我需要避免使用赋值或循环。@user3277752该解决方案不使用循环,只使用递归。我编辑了我的答案,使之更加明确。你会如何将其转换为一个迭代过程?@user3277752这在这种情况下很棘手。我们必须将递归调用转换为尾部递归。我猜想这是可能的,但不清楚如何实现。@user3277752另一种可能是使用延续传递样式,它可以将任何递归过程转换为迭代过程。同样,实现起来有点棘手,也更难理解