如何使用递归对字符串列表进行排序?

时间:2019-06-22 21:28:18

标签: scheme racket

我正在尝试编写代码,在该代码中,它仅使用递归而不使用其他任何东西来创建按递增顺序排列的字符串列表。

我应该怎么做?

(define (create-list n st)
  (cond [(zero? n) ""]
        [else (string-append "X" (create-list (sub1 n)  st))]))

(define (stair n)
   (cond [(equal? n 0) empty]
              [else (cons (create-list n "x") (stair (- n 1)))]))

;; (stair 4) --> (list "XXXX" "XXX" "XX" "X")

所需的输出:(list "X" "XX" "XXX" "XXXX")

2 个答案:

答案 0 :(得分:1)

替换

(cons (create-list n "x") (stair (- n 1)))

使用

(append (stair (- n 1)) (list (create-list n "Q")))

(请注意,create-list实际上并未使用st参数。)

答案 1 :(得分:1)

所有方案列表都是从头到尾创建的。您要先创建("XXXX"),然后再创建("XXX" "XXXX"),等等。无论何时执行(cons "X" (recursion ....))(recursion ...)都需要在cons之前完成,而最有效的方法是使用一个累加器。由于append为O(n),因此使用append的每个步骤都会闻到错误,因此,如果您这样做,则每个步骤都会有O(n ^ 2)。通过几千个元素,您将开始注意到差异。

您不需要create-list,它不会创建列表而是一个字符串,因为Scheme具有make-string可以满足您的需求:

(make-string 3 #\X) ; ==> "XXX"

所以这是楼梯:

(define (stair n)
  (define (xs n)
    (make-string n #\X))
  (let helper ((n n) (acc '()))
    (if (zero? n)
        acc
        (helper (- n 1) 
                (cons (xs n) acc)))))

因此,在这种情况下,如果您希望以相反的顺序使用它,那么您将使用与n不同的名称,然后向上使用,直到通过了n和。有时,您没有选择的余地,例如,如果要复制列表,则通常可以构建相反的结果,然后反转结果。有时您需要使用内存并需要延续,但这会限制程序停止工作之前结构的深度。在球拍的情况下,直到耗尽了您提供的整个堆内存后,它才会停止。