FizzBu​​zz Lambda 只返回最后一个整数

FizzBuzz Lambda Only Returning Last Integer

我是 Scheme 的新手,正在尝试编写示例 FizzBu​​zz 函数。规则如下:

这是我的代码:

(define (fizzbuzz n)
  (print (fizzbuzz1 1 n)))

;; Helper function for fizzbuzz
(define (fizzbuzz1 i n)
  (cond [(and (= 0 (modulo i 3)) (= 0 (modulo i 5)))
         " fizzbuzz "]
        [(= 0 (modulo i 3))
         " fizz "]
        [(= 0 (modulo i 5))
         " buzz "]
        (i))

  (cond [(< i n) (fizzbuzz1 (+ 1 i) n)]))

(fizzbuzz 21)

但它显示的只是“21”(来自测试用例)。有人可以帮我吗?

编辑:稍微修正了我的代码并更新了它,但现在我得到的是 #<void> 打印出来。

你的函数实际上计算了从 1 到 21 的所有数字的正确结果,只是你没有做任何事情来在输出中显示它们,或者以某种方式收集它们,以便它们在被“丢失”之后在fizzbuzz1里面计算(最初的print只打印fizzbuzz1的结果,也就是#<void>)。如果你想显示它们(通过使用 display 而不是 print,以获得更美观的结果),你可以在 cond 的每个分支中放置一个 display,因为像这样的例子(请注意,如果你想学习这些语言,你绝对应该开始以干净的方式缩进你的函数!):

(define (fizzbuzz n)
  (fizzbuzz1 1 n))

(define (fizzbuzz1 i n)
  (cond [(and (= 0 (modulo i 3) ) (= 0 (modulo i 5) ))
         (display " fizzbuzz ")]
        [(= 0 (modulo i 3))
         (display " fizz ")]
        [(= 0 (modulo i 5))
         (display " buzz ")]
        [else (display i) (display " ")]
        )
  (cond [(< i n) (fizzbuzz1 (+ 1 i) n)])
  )

还请注意,最后的 #void 是由于 fizzbuzz 初始定义中打印函数的值,如果删除它,它将消失。

另一个,更优雅,可能是在计算所有字符串时收集它们,例如通过使用string-append,就像在这个函数中:

(define (fizzbuzz n)
   (fizzbuzz1 1 n))

(define (fizzbuzz1 i n)
  (if (> i n)
      ""
      (string-append
       (cond [(and (= 0 (modulo i 3) ) (= 0 (modulo i 5) ))
              " fizzbuzz "]
             [(= 0 (modulo i 3))
              " fizz "]
             [(= 0 (modulo i 5))
              " buzz "]
             [else (~a " " i " ")]
             )
       (fizzbuzz1 (+ 1 i) n))))

请注意,如果您的程序在交互式环境(如 DrRacket)中使用,在这种情况下也没有必要“打印”结果。

编辑

此解决方案的效率低于第一个解决方案,但如果您需要以某种结构收集所有结果以将它们用于其他任务,应该可以让您了解程序应具有何种结构。作为另一个示例,您可以使用 cons 来收集它们,例如,生成一个字符串列表而不是单个字符串(只需将 '() 替换为 ""cons string-append).

此外,如果您使用球拍(因为您使用了球拍标签),您可能会发现球拍的 for 结构在这里很有用。

使用 for(如 Renzo 所说,使用 display)你可以这样写 fizzbuzz:

#lang racket

(define (fizzbuzz n)
  (for ([i (in-range n)])
    (cond [(and (= 0 (modulo i 3)) (= 0 (modulo i 5)))
           (displayln "fizzbuzz")]
          [(= 0 (modulo i 3))
           (displayln "fizz")]
          [(= 0 (modulo i 5))
           (displayln "buzz")]
          [else (displayln i)])))

(fizzbuzz 21)

另一种选择是使用for/list,类似于for,但将结果累加到列表中:

#lang racket

(define (fizzbuzz n)
  (for/list ([i (in-range n)])
    (cond [(and (= 0 (modulo i 3)) (= 0 (modulo i 5)))
           "fizzbuzz"]
          [(= 0 (modulo i 3))
           "fizz"]
          [(= 0 (modulo i 5))
           "buzz"]
          [else i])))

(fizzbuzz 21)
(apply string-append (fizzbuzz 21))