0

我正在使用带有完整 Swindle 包的 Scheme,并且我正在尝试使用条件来递归地确定整数的偶数/奇数。我的代码如下:

(define (odd? x)(
            (cond 
              ((= x 0) '#f)
              ((= x 1) '#t)
              ((= (even? (- x 1)) #t) '#f)
              (else '#t))))

(define (even? x)(
              (cond
                ((= x 0) '#f)
                ((= x 2) '#t)
                ((= (odd? (- x 1)) #t) '#f)
                (else '#t))))

但是,当我运行 (even?x) 或 (odd?x) [x 是某个数字,没关系,因为我得到同样的错误] 我得到:应用程序:不是过程;期望一个可以应用于给定参数的过程:#t arguments...:[none]

任何人都可以帮忙吗?谢谢。我不是 100% 熟悉理想的 Scheme 语法,所以可能就是这样。

4

2 回答 2

0

您在表达式周围有一对错误的括号cond(这会导致报告的错误)。但是,每个过程中的条件太多了,并且因为您=用于将数字与布尔值进行比较,所以会有一个点会发生违反合同的情况。对于修复,您可以在此处替换=为:equal?

((equal? (even? (- x 1)) #t) '#f)

在这里:

((equal? (odd? (- x 1)) #t) '#f)

但是,程序仍然会给出不正确的结果:

(even? 5)
=> #t
(odd? 7)
=> #f

老实说,我认为最好简化实现,这样可以解决所有问题。试试这个:

(define (odd? x)
  (cond ((= x 0) #f)
        (else (even? (- x 1)))))

(define (even? x)
  (cond ((= x 0) #t)
        (else (odd? (- x 1)))))

现在我们将得到正确答案:

(even? 4)
=> #t
(even? 5)
=> #f
(odd? 6)
=> #f
(odd? 7)
=> #t
于 2013-11-10T04:51:30.733 回答
0

括号中的任何 Scheme 形式都是一个应用程序,例如(sin 42)(42 sin)。第一个sin作为带参数的函数调用42并产生一个值;第二个尝试42使用参数调用sin,但42不是过程,因此会导致错误。同样(42)是没有参数的应用程序;它仍然必须有一个过程作为它的第一部分应用,在没有参数的情况下被调用,对吧?在 Scheme 中,括号很重要,它们不仅仅用于对内容进行分组(因为它们可能在其他一些语言中)。所以额外的括号会导致额外的尝试评估结果,这是一个布尔值,即不是一个过程,所以这是一个错误。

那么,'#f就是#f;类似地#t(他们都对自己进行评估);并且条件1与 just 相同(产生相同的布尔结果集)((我们不能使用1来比较布尔值,它应该只与数字一起使用))(= test #t) (equal? test #t)test=

(define (odd? x)
        (cond 
          ((= x 0) #f)
          ((= x 1) #t)
          ((even? (- x 1)) #f)
          (else #t)))

此外,(if test #f else...)与以下内容相同(if (not test) else... #f)

(define (odd? x)
        (cond 
          ((= x 0) #f)
          ((= x 1) #t)
          ((not (even? (- x 1))) #t)
          (else #f)))                 ; (else ...) is like (#t ...)

使用逻辑连接词可以合并具有相同结果的子句,并且可以重新排列互斥子句(可以通过显式保护实现互斥性):

(define (odd? x)
        (cond 
          ((and (/= x 0)              ; a guard
                (or (= x 1) 
                    (not (even? (- x 1))))) #t)
          ((or (= x 0) #t) #f)))

(cond (test #t) (else #f)就是(if test #t #f)这样test

(define (odd? x) (and (> x 0)         ; `>` is better
                      (or (= x 1) 
                          (not (even? (- x 1))))))

守卫(> x 0)可以防止负xes 的失败。

但是,这是完全错误的。为n奇,n-1 为偶,而不是相反!

(define (odd? x) (and (> x 0)         ; work only for positive integers
                      (or (= x 1) 
                          (even? (- x 1)))))

我们可以写(not (odd? (- x 1))),但它不会是尾递归的。这尾递归模 consnot用作“构造函数”),但由于某种历史性的侥幸原因2,TRMC 优化不是 Scheme 实现所必需的。and和forms 中的最后一个表达式or实际上是在 tail position。但不在not. ((2尽管早在1974年就被描述了。))

对 的定义重复相同的操作even?

于 2013-11-10T07:53:46.237 回答