1

我正在用 Scheme 编写一个函数,它应该采用两个整数 X 和 Y,然后递归相加X/Y + (X-1)/(Y-1) + ...,直到其中一个数字达到 0。

例如,取 4 和 3:

4/3 + 3/2 + 2/1 = 29/6

这是我的功能无法正常工作:

(define changingFractions (lambda (X Y)
    (cond 
        ( ((> X 0) and (> Y 0)) (+ (/ X Y) (changingFunctions((- X 1) (- Y 1)))))
        ( ((= X 0) or (= Y 0)) 0)
    )
))

编辑:我已经更改了我的代码以解决评论中列出的问题,以及更改 和 的or位置and

(define changingFractions (lambda (X Y)
    (cond 
        ( (and (> X 0) (> Y 0)) (+ (/ X Y) (changingFunctions (- X 1) (- Y 1) )))
        ( (or (= X 0) (= Y 0)) 0)
    )
))

不幸的是,我仍然遇到错误。

4

2 回答 2

5

那里有几个问题:

  • 您应该使用语法定义函数(define (func-name arg1 arg2 ...) func-body),而不是将 lambda 函数分配给变量。
  • andor函数一样使用,将它们作为表单中的第一个元素((and x y)而不是(x and y))。不是让他们在论点之间。
  • 您在递归调用的函数参数周围有一组额外的括号,并且您changingFunctions在名称为changingFractions.
  • 不是错误,但不要将右括号放在自己的行上。
  • Lisps 中的命名约定是使用破折号,而不是驼峰式(changing-fractions而不是changingFractions)。

随着那些固定:

(define (changing-fractions x y)
  (cond 
   ((and (> x 0) (> y 0)) (+ (/ x y) (changing-fractions (- x 1) (- y 1))))
   ((or (= x 0) (= y 0)) 0)))

但是您可以将其更改cond为 anif以使其更清晰:

(define (changing-fractions x y)
  (if (and (> x 0) (> y 0))
      (+ (/ x y) (changing-fractions (- x 1) (- y 1)))
      0))
于 2016-02-04T16:01:32.453 回答
1

我个人喜欢这个实现。与此处提供的其他答案不同,它具有适当的尾调用。

(define (changing-fractions x y (z 0))
  (cond ((zero? x) z)
        ((zero? y) z)
        (else (changing-fractions (sub1 x) (sub1 y) (+ z (/ x y))))))

(changing-fractions 4 3) ; => 4 5/6

诀窍是z默认为的可选参数0。使用这个累加器,我们可以在每次changing-fractions递归时迭代地建立小数和。将此与@jkliski 的答案中为每个递归添加的附加堆栈帧进行比较

; changing-fractions not in tail position...
(+ (/ x y) (changing-fractions (- x 1) (- y 1)))
于 2016-02-05T13:54:26.173 回答