【问题标题】:Any idea of printing in Racket?在 Racket 中打印的任何想法?
【发布时间】:2015-10-11 01:04:11
【问题描述】:

我一直在努力做到这一点,但我实际上无法做到这一点令人沮丧。我什至对发布我编写的代码感到尴尬。我是递归新手,所以我需要一些帮助。 我正在尝试做的是像这样定义一个函数星:

> (star 5)
*
**
***
****
*****

它应该在下一行打印*,然后是**,依此类推,直到你输入的数字。 一个经典的初学者练习,但在带有递归的 Racket 中要困难得多。谢谢。

【问题讨论】:

    标签: scheme lisp racket


    【解决方案1】:

    您没有发布您尝试的解决方案,所以我只能给您一些提示,希望您自己得出答案;只需填写空白;)。

    如果我们把问题分成两部分会更容易。首先,弄清楚如何创建一个重复另一个字符串n 次的字符串——让我们为此编写一个辅助过程:

    (define (repeat s n)
      (cond ((zero? n) <???>) ; base case
            (else
             (string-append s
                            (repeat s <???>))))) ; advance recursion
    

    请注意,我们还可以使用make-string 来获得更简单的答案,如@ThrowawayAccount3Million 的答案所示。无论如何,结果应该是这样的:

    (repeat "*" 3)
    => "***"
    

    现在我们只需要在我们的star 过程中在正确的位置调用它:

    (define (star n)
      (cond ((not (zero? n))
             (star <???>) ; advance recursion
             (displayln (repeat <???> <???>))))) ; call helper
    

    就是这样!

    (star 5)
    => *
       **
       ***
       ****
       *****
    

    【讨论】:

      【解决方案2】:

      仅使用递归从 1 迭代到 5:

      (let loop ((n 1))
          (cond ((> n 5)
                 (void))
                (else
                  (displayln ...)
                  (loop (+ 1 n)))))
      

      上面相当于定义了一个名为loop的函数,然后调用它,像这样:

      (define (loop n)
          (cond ((> n 5)
                 (void))
                (else
                  (displayln ...)
                  (loop (+ 1 n)))))
      (loop 1)
      

      这可以出现在另一个函数的主体内:

      (define (stars num-stars)
          (define (loop ...
      

      要打印 n 颗星:

       (displayln (make-string n #\*))
      

      Racket 不是原始的 Scheme,它有自己的循环结构,您也可以使用它:

       (for ((n (in-range 1 6)))
          (displayln ...))
      

      还有一个库实现了 Common Lisp/Maclisp 中的 loop 构造(也有 Chicken Scheme 和 EMACS Lisp 的实现):

      (require (planet jphelps/loop)) ;; Download, install, and
                                      ;; use the library.
      (loop for n from 1 to 5
          do (displayln ...))
      

      【讨论】:

        【解决方案3】:

        这是编写带有递归函数调用的循环的一种方法:

        (define (loop from to f done)
          (if (< from to)
              (begin
                (f from)
                (loop (+ from 1) to f done))
              (done)))
        

        如果from 小于to,则循环使用参数from 调用函数f,然后使用from+1 调用loop。如果from 等于to,则循环完成并调用函数done

        Example:
        > (loop 0 5 display newline)
        01234
        

        让我们定义一个显示单个星的助手:

        (define (display-star _)
          (display "*"))
        

        我们现在可以定义display-stars,它显示n 星号并通过打印换行符结束。

        (define (display-stars n)
          (loop 0 n display-star newline))
        

        原来的问题现在可以这样解决了:

        > (loop 1 6 display-stars void)
        *
        **
        ***
        ****
        *****
        

        完整的程序:

        #lang racket
        
        
        (define (loop from to f done)
          (if (< from to)
              (begin
                (f from)
                (loop (+ from 1) to f done))
              (done)))
        
        
        (define (display-stars n)
          (loop 0 n display-star newline))
        
        (loop 1 6 display-stars void)
        

        使用循环构造for的替代解决方案:

        > (for ([i (in-range 1 6)])
            (for ([j i])
              (display "*"))
            (newline))
        *
        **
        ***
        ****
        *****
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-11-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-04-03
          • 1970-01-01
          • 2014-09-11
          • 1970-01-01
          相关资源
          最近更新 更多