递归函数没有按计划工作
Recursive function not working as planned
我正在用 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)
)
))
不幸的是,我仍然遇到错误。
那里有几个问题:
- 您应该使用
(define (func-name arg1 arg2 ...) func-body)
语法定义函数,而不是将 lambda 函数分配给变量。
-
and
和 or
的用法类似于函数,将它们作为表单中的第一个元素((and x y)
而不是 (x and y)
)。不是通过将它们放在参数之间。
- 您在递归调用的函数参数周围有一组额外的括号,当名称为
changingFractions
. 时您写了 changingFunctions
- 不是错误,但不要将右括号放在自己的行上。
- 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
更改为 if
以使其更清楚:
(define (changing-fractions x y)
(if (and (> x 0) (> y 0))
(+ (/ x y) (changing-fractions (- x 1) (- y 1)))
0))
我个人喜欢这个实现。与此处提供的其他答案不同,它有一个正确的尾调用。
(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
诀窍是默认为 0
的可选 z
参数。使用这个累加器,我们可以在每次 changing-fractions
递归时迭代地建立小数和。将此与@jkliski 的回答中为每个递归添加的额外堆栈帧进行比较
; changing-fractions not in tail position...
(+ (/ x y) (changing-fractions (- x 1) (- y 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)
)
))
不幸的是,我仍然遇到错误。
那里有几个问题:
- 您应该使用
(define (func-name arg1 arg2 ...) func-body)
语法定义函数,而不是将 lambda 函数分配给变量。 -
and
和or
的用法类似于函数,将它们作为表单中的第一个元素((and x y)
而不是(x and y)
)。不是通过将它们放在参数之间。 - 您在递归调用的函数参数周围有一组额外的括号,当名称为
changingFractions
. 时您写了 - 不是错误,但不要将右括号放在自己的行上。
- Lisps 中的命名约定是使用破折号,而不是驼峰式(
changing-fractions
而不是changingFractions
)。
changingFunctions
固定了那些:
(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
更改为 if
以使其更清楚:
(define (changing-fractions x y)
(if (and (> x 0) (> y 0))
(+ (/ x y) (changing-fractions (- x 1) (- y 1)))
0))
我个人喜欢这个实现。与此处提供的其他答案不同,它有一个正确的尾调用。
(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
诀窍是默认为 0
的可选 z
参数。使用这个累加器,我们可以在每次 changing-fractions
递归时迭代地建立小数和。将此与@jkliski 的回答中为每个递归添加的额外堆栈帧进行比较
; changing-fractions not in tail position...
(+ (/ x y) (changing-fractions (- x 1) (- y 1)))