3

我的问题是我如何编码

(triangle 5) produces (list "*****" "****" "***" "**" "*")

注意:(5 个星号 4,然后是 3,然后是 2,然后是 1)。到目前为止,我有:

(define (triangle n)
  (cond
    [(zero? n) empty]
    [else (cons n (triangle (sub1 n)))]))

但这只会给我(list 5 4 3 2 1)。请注意,这仅使用基本的方案初学者列表和缩写。谢谢!

4

3 回答 3

4

将复杂问题拆分为更简单、更短的子部分总是一个好主意。在这种情况下,我们可以通过首先编写子问题的解决方案来简化通用解决方案,如下所示:

  1. 首先,构建一个创建字符串列表的过程,其中字符串是"*****"or"****"或 ... or"*"
  2. 其次,编写一个repeat帮助程序,给定一个字符串和一个数字,重复该字符串多次 - 例如:(repeat "*" 3)将返回"***"

很容易看出如何用第二个子问题来表达第一个子问题。因为这看起来像一个家庭作业,所以你不应该在这里要求完整的解决方案。自己来回答对你来说会更有用,这里是大意,填空:

(define (triangle n)
  (cond [<???> <???>]                 ; if n is zero return the empty list: '()
        [else                         ; otherwise
         (cons <???>                  ; cons n repetitions of * (using `repeat`)
               (triangle <???>))]))   ; and advance the recursion

(define (repeat str n)
  (cond [<???> <???>]                 ; if n is zero return the empty string: ""
        [else                         ; otherwise
         (string-append <???>         ; append the given string
             (repeat <???> <???>))])) ; and advance the recursion

如果你仔细看,这两个过程共享完全相同的结构。改变的是在基本情况下返回的值(一个空列表和一个空字符串)以及用于将部分答案(consstring-append)粘在一起的过程。

于 2013-03-10T21:57:13.773 回答
1

如果您只是在寻找如何将数字转换为字符串,您可以使用(number->string x).

但是,由于您希望将数字表示为星号,因此最好将它们保留为数字,直到您构建了一串星号。在这种情况下,您可能需要这样的方法:

(define (num-to-asterisks x)
        (make-string x #\*))
于 2013-03-10T21:52:54.737 回答
0

试试这个:

(define (triangle n)
  (let building ((i 0) (r '()))
    (if (= i n)
        r
        (building (+ i 1)
                  (cons (string-append "*" (if (null? r) "" (car r)))
                         r)))))

这是很好的尾递归;通过将“*”添加到结果列表的第一个元素来构建结果列表。

于 2013-03-11T00:48:26.187 回答