【问题标题】:How to find the n-th term of a GP in Scheme using recurrence?如何使用递归找到Scheme中GP的第n项?
【发布时间】:2021-05-08 02:59:30
【问题描述】:

我正在尝试使用 Scheme 中的递归算法查找 GP 的第 N 项,但我遇到了这个错误。 “交互被禁用;内存不足” 第一项是a,r是公比,n是序列的第n项。 第 n 项是 a* r^(n-1)。 所以 (nth 4 2 2) 必须返回 16。 (2, 4, 8, 16) 其中 a=2 和 r=2。

( define (nth n r a)
   (cond
     ((eq? n 0) 1)
     ((eq? r 0) #f)
     ( * a (nth (- n 1) r a))
   )
   )

【问题讨论】:

  • 基本情况是什么?也就是说,你的递归过程是如何停止的?
  • 您还应该解释您认为 GP 是什么,以及您的函数的参数如何表示一个。

标签: recursion scheme lisp racket


【解决方案1】:

显然你的意思是几何级数,其中

Tn     =  a*rn-1        -- and so, also
Tn-1   =  a*rn-2        -- and thus
Tn     =  Tn-1 * r, 
          Tn-1  =  Tn-2 * r, 
             ......., 
                     T1  =  a*r0  =  a

【讨论】:

    【解决方案2】:

    原始代码没有基本情况,这就是它以内存不足错误结束的原因。递归过程没有定义的停止点,因此它一直运行到没有更多可用内存为止。

    尽管问题声称,更新后的代码并没有耗尽内存;但是代码不正确。

    更新后的代码为 (nth 4 2 2) 返回 1:

    (define (nth n r a)
      (cond
        ((eq? n 0) 1)
        ((eq? r 0) #f)
        (* a (nth (- n 1) r a))))
    
    gp.rkt> (nth 4 2 2)
    1
    

    问题是最后的conditional clause:(* a (nth (- n 1) r a))

    条件子句是一个带括号的表达式,包含一个测试表达式和一个或多个主体表达式,即(<test-exp> <body-exp> ...+)。在发布的代码中,* 代替了<test-exp>,并且始终评估为真。然后评估剩余的表达式。由于这些表达式中的最后一个是对nth 的递归调用,因此该过程一直持续到n 为零,此时返回1。没有对返回值执行进一步的操作(因为 * 被评估为测试表达式,a 的值被丢弃),所以 nth总是返回 1非负n 和正r

    解决这个问题需要一个else 子句:

    (define (nth n r a)
      (cond ((eq? n 0) 1)
            ((eq? r 0) #f)
            (else
             (* a (nth (- n 1) r a)))))
    
    gp.rkt> (nth 4 2 2)
    16
    

    顺便说一句,eq? 通常不适合与数字一起使用。在 Racket 中,它适用于fixnums,它在这里有效,因为输入是与精确整数类型相比的精确整数类型。在其他 lisps 中,这不太可能按预期工作。通常您应该使用= 进行数字比较,甚至使用zero? 将数字与零进行比较。

    通常我会为此使用zero?,因为它是用于此用途的最具体的程序:

    (define (nth n r a)
      (cond ((zero? n) 1)
            ((zero? r) #f)
            (else
             (* a (nth (- n 1) r a)))))
    

    【讨论】:

      猜你喜欢
      • 2019-06-26
      • 2021-06-30
      • 2017-06-05
      • 1970-01-01
      • 2019-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-06
      相关资源
      最近更新 更多