简体   繁体   English

方案:递归zeno函数

[英]Scheme: recursive zeno function

The following is a function that sums 1/2^n until it reaches 0 . 以下是一个将1/2 ^ n加到0的函数。 Can someone tell me whether or not I need an else statement, and how to arrange my parenthesis so there are no compile errors? 有人可以告诉我是否需要else语句,以及如何排列括号以确保没有编译错误吗?

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

I have my hat, my tea, and nothing to do for a while at work. 我戴上帽子,喝茶,上班没时间做。 You know what time it is. 你知道现在几点了。

[dons code-review hat] [不带密码审查帽]

Firstly, if you had properly indented your code, it would read 首先,如果您正确缩进了代码,它将显示为

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

if in Scheme is not like the if / then / else construct of C-like languages. if in Scheme不像C语言一样的if / then / else构造。 It's actually the ternary operator . 实际上是三元运算符 In other words, else makes no sense in this context. 换句话说,在这种情况下, else毫无意义。

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

You don't need to use + to return a number; 您不需要使用+来返回数字; numbers are self-evaluating. 数字是自我评估的。

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

When you have an expression like (foo bar baz) , it usually means 当您具有(foo bar baz)这样的表达式时,通常表示

"Call the function foo with arguments bar and baz " “使用参数barbaz调用函数foo

You can't just add extra parentheses as you please; 您不能随便添加多余的括号。 those change the meaning of the expression. 这些改变了表达的含义。 For example, ((foo) (bar baz)) means 例如, ((foo) (bar baz))意思是

"Call the function foo with no arguments, and call its result with the result of calling bar with the argument baz " “不带参数调用函数foo ,并以带参数baz调用bar的结果来调用其结果”

In other words, 换一种说法,

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

what you're saying, and almost certainly don't mean, here is 您在说什么,几乎可以肯定不是在这里,这是

"Call the function (+ (/ 1 (expt 2 n))) with the result of calling the result of calling zeno with the argument (- n 1) with no arguments." “调用函数(+ (/ 1 (expt 2 n)))的结果是调用不带参数的参数(- n 1)调用zeno的结果。”

What you seem to mean is 你似乎的意思是

"Add 1 divided by 2^n to the result of calling zeno with one less than n " “将调用zeno的结果加1除以2^n ,且n小于n

Which means that what you should say is 这意味着您应该说的是

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

You have a couple of syntax errors (erroneous parenthesis, mostly), and the if form doesn't use else - don't get me wrong, it does have an "else" part, it's just that you must not explicitly write else for it to work. 你有几个语法错误(错误的括号内,多),并且if形式不使用else -不要误会我的意思,它确实有一个“其他”的一部分,它只是你不能明确写入else的它起作用。 I believe this is what you were aiming for: 我相信这就是您的目标:

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

For a completely different approach, this uses an explicit do loop to do the summing. 对于完全不同的方法,这使用显式的do循环进行求和。 It avoids using expt (by design). 它避免使用expt (通过设计)。

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

It may or may not be more readable when written into its equivalent named let form: 将其写入等效的名为let形式时,它可能会或可能不可读:

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

For an even more completely different approach, you can use SRFI 41 streams: 对于更完全不同的方法,可以使用SRFI 41流:

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

(The above snippet also requires SRFI 26 to be loaded, in addition to SRFI 41.) (以上代码段也需要SRFI 26被加载,除了SRFI 41)


An even even more completely different approach: just use the closed-form solution! 甚至更完全不同的方法:仅使用封闭形式的解决方案! (Thanks, WorBlux.) (谢谢,WorBlux。)

(define (zeno n)
  (- 1 (/ (expt 2 n))))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM