Scheme 递归函数未按计划工作

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)))))

我正在用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)
    )
))
编辑:我修改了代码以修复注释中列出的问题,并更改了
的位置

(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函数?
(