0

以下是对 1/2^n 求和直到达到 0 的函数。有人可以告诉我是否需要 else 语句,以及如何安排括号以防止编译错误?

(define (zeno n)
  (if (= n 0)
      (+ 0)
      (else
        ((+ (/ 1 (expt 2 n )))
         ((zeno(- n 1)))))))
4

3 回答 3

3

我有我的帽子,我的茶,在工作中有一段时间无事可做。你知道现在几点了。

[dons code-review hat]

首先,如果您正确缩进了您的代码,它将显示为

(define (zeno n)
    (if (= n 0)
        (+ 0)
        (else
         ((+ (/ 1 (expt 2 n)))
          ((zeno (- n 1)))))))

if在Scheme中不像if//类C 语言的构造。它实际上是三元运算符。换句话说,在这种情况下没有任何意义。thenelseelse

(define (zeno n)
    (if (= n 0)
        (+ 0)
        ((+ (/ 1 (expt 2 n)))
         ((zeno (- n 1)))))))

你不需要使用+来返回一个数字;数字是自我评估的。

(define (zeno n)
    (if (= n 0)
        0
        ((+ (/ 1 (expt 2 n)))
         ((zeno (- n 1)))))))

当你有一个像这样的表达时(foo bar baz),它通常意味着

“调用foo带有参数的函数barbaz

您不能随意添加额外的括号;那些改变了表达的意思。例如,((foo) (bar baz))意味着

“不带参数调用函数,并用带参数foo调用的结果调用其结果”barbaz

换句话说,

...
((+ (/ 1 (expt 2 n)))
 ((zeno (- n 1))))))

你在说什么,几乎可以肯定不是这个意思,这里是

“使用不带参数的参数(+ (/ 1 (expt 2 n)))调用结果调用函数。”zeno(- n 1)

你的意思似乎是

"用小于一的调用结果加上1除以"2^nzenon

这意味着你应该说的是

(define (zeno n)
    (if (= n 0)
        0
        (+ (/ 1 (expt 2 n))
           (zeno (- n 1)))))
于 2013-09-03T15:08:24.230 回答
1

对于完全不同的方法,这使用显式do循环来进行求和。它避免使用expt(按设计)。

(define (zeno n)
  (do ((n n (- n 1))
       (sum 0 (+ sum frac))
       (frac 1/2 (/ frac 2)))
      ((zero? n) sum)))

当写成等效的命名let形式时,它可能更具可读性,也可能不更具可读性:

(define (zeno n)
  (let loop ((n n)
             (sum 0)
             (frac 1/2))
    (if (zero? n)
        sum
        (loop (- n 1) (+ sum frac) (/ frac 2)))))

对于更完全不同的方法,您可以使用SRFI 41流:

(define zeno
  (let ((frac-stream (stream-iterate (cut / <> 2) 1/2)))
    (lambda (n)
      (stream-fold + 0 (stream-take n frac-stream)))))

(除了 SRFI 41 之外,上面的代码片段还需要加载SRFI 26。)


甚至更完全不同的方法:只需使用封闭形式的解决方案!(谢谢,WorBlux。)

(define (zeno n)
  (- 1 (/ (expt 2 n))))
于 2013-09-03T15:14:05.707 回答
1

您有几个语法错误(主要是错误的括号),并且if表单没有使用else- 不要误会我的意思,它确实有一个“else”部分,只是您不能明确地写else它才能工作. 我相信这就是您的目标:

(define (zeno n)
  (if (= n 0)
      0
      (+ (/ 1 (expt 2 n))
         (zeno (- n 1)))))
于 2013-09-03T14:46:02.680 回答