以下是将1/2 ^ n求和直到达到0的函数。有人能告诉我是否需要else语句,以及如何安排我的括号以便没有编译错误?
(define (zeno n)
(if (= n 0)
(+ 0)
(else
((+ (/ 1 (expt 2 n )))
((zeno(- n 1)))))))
答案 0 :(得分:3)
我戴着帽子,喝茶,工作一段时间无事可做。你知道现在几点了。
[dons code-review帽子]
首先,如果您的代码有properly indented,则会显示
(define (zeno n)
(if (= n 0)
(+ 0)
(else
((+ (/ 1 (expt 2 n)))
((zeno (- n 1)))))))
if
与C语言的if
/ then
/ else
结构不同。它实际上是ternary operator。换句话说,else
在这种情况下毫无意义。
(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
和bar
调用函数baz
”
您不能随意添加额外的括号;那些改变了表达的意思。例如,((foo) (bar baz))
表示
“不带参数调用函数
foo
,并使用参数bar
调用baz
的结果调用其结果”
换句话说,
...
((+ (/ 1 (expt 2 n)))
((zeno (- n 1))))))
你在说什么,而且几乎肯定不是,这里是
“使用不带参数的参数
(+ (/ 1 (expt 2 n)))
调用zeno
调用结果调用函数(- n 1)
。”
你的意思是
“将
1
除以2^n
添加到调用zeno
的结果中,其中一个小于n
”
这意味着你应该说的是
(define (zeno n)
(if (= n 0)
0
(+ (/ 1 (expt 2 n))
(zeno (- n 1)))))
答案 1 :(得分:1)
你有几个语法错误(大多数是错误的括号),if
表单不使用else
- 不要误解我的意思, >有一个“其他”部分,只是你不能明确地写else
来使它工作。我相信这就是你的目标:
(define (zeno n)
(if (= n 0)
0
(+ (/ 1 (expt 2 n))
(zeno (- n 1)))))
答案 2 :(得分: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))))