Scheme 递归函数未按计划工作
我正在用Scheme编写一个函数,它应该取两个整数X和Y,然后递归地加上Scheme 递归函数未按计划工作,scheme,lisp,sisc,Scheme,Lisp,Sisc,我正在用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/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)
)
))
编辑:我修改了代码以修复注释中列出的问题,并更改了或和和的位置
(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函数指定给变量
和
以及或
与函数类似,它们作为表单中的第一个元素((和xy)
,而不是(x和y)
)。而不是让他们在争论之间
- 在递归调用的函数参数周围有一组额外的参数,当名称为
changingfracts
时,您编写了changingFunctions
- 这不是一个错误,但不要将结束参数放在它们自己的行上
- Lisps中的命名约定是使用破折号,而不是camelcase(
更改分数
,而不是更改分数
)
对于那些固定的:
(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(func name arg1 arg2…)func body)
定义函数,而不是将lambda函数指定给变量
和
以及或
与函数类似,它们作为表单中的第一个元素((和xy)
,而不是(x和y)
)。而不是让他们在争论之间
- 在递归调用的函数参数周围有一组额外的参数,当名称为
changingfracts
时,您编写了changingFunctions
- 这不是一个错误,但不要将结束参数放在它们自己的行上
- Lisps中的命名约定是使用破折号,而不是camelcase(
更改分数
,而不是更改分数
)
对于那些固定的:
(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
技巧是可选的z
参数,默认为0
。使用此累加器,我们可以在每次更改分数
递归时迭代地建立分数和。将此与@jkliski的答案中为每个递归添加的附加堆栈帧进行比较
; changing-fractions not in tail position...
(+ (/ x y) (changing-fractions (- x 1) (- y 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
。使用此累加器,我们可以在每次更改分数
递归时迭代地建立分数和。将此与@jkliski的答案中为每个递归添加的附加堆栈帧进行比较
; changing-fractions not in tail position...
(+ (/ x y) (changing-fractions (- x 1) (- y 1)))
当某些东西“工作”不正常时,请提供错误消息。在这里,我想(-x1)
不是一个函数会导致一个问题。您应该尝试(changingFunctions(-x1)-y1))
而不是将参数括在括号中。如果第一次测试失败,您真的需要检查x和y是否都为零吗?如果您的任何参数为负,则函数的返回值每秒未指定。@coredump-问题将在联机应用程序中完成。是它给我的错误。你的第一个建议很有道理,我已经调整了代码,但它还是有点错误。我也试过你的第二个建议,但也不能解决问题。我知道没有必要,但我希望基本情况可见。嗯。。。改变分数!=changingFunctions“不幸的是,我仍然得到了一个错误。”这将有助于在问题中显示该错误……当某些东西不能正确“工作”时,请提供一条错误消息。在这里,我想(-x1)
不是一个函数会导致一个问题。您应该尝试(changingFunctions(-x1)-y1))
而不是将参数括在括号中。如果第一次测试失败,您真的需要检查x和y是否都为零吗?如果您的任何参数为负,则函数的返回值每秒未指定。@coredump-问题将在联机应用程序中完成。是它给我的错误。你的第一个建议很有道理,我已经调整了代码,但它还是有点错误。我也试过你的第二个建议,但也不能解决问题。我知道没有必要,但我希望基本情况可见。嗯。。。改变分数!=changingFunctions“不幸的是,我仍然得到了一个错误。”如果能在问题中显示出这个错误,会有帮助的……谢谢你所有的更正。我唯一不明白的问题是何时/何时不使用lambda函数?(define(func)p1 p2…
是(define func(lambda(p1 p2…))
@cornontekob使用lambda
生成的函数通常在需要高阶函数时以特别方式使用(map
等)函数太具体或太琐碎,无法命名,或者函数需要使用当前作用域中的变量(闭包)。当您想延迟求值时,也可以使用lambda。感谢您的所有更正。我不明白的唯一问题是何时/何时不使用lambda函数?(