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

Scheme 如何使用递归对字符串列表排序?,scheme,racket,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

我正在尝试编写代码,其中只使用递归而不使用其他方法创建一个递增顺序的字符串列表

我该怎么做呢

(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")
所需输出:
(列出“X”“XX”“XXX”“XXXX”)
替换

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

(请注意,
create list
实际上没有使用
st
参数。)

替换

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


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

所有方案列表都是从头到尾创建的。您需要先创建
(“XXXX”)
,然后创建
(“XXX”“XXXX”)
等。无论何时创建
(cons“X”(递归…))
,然后
(递归…
都需要在
cons
之前完成,而最有效的方法是使用累加器。使用
append
每个步骤都有错误的味道,因为
append
是O(n),所以如果每个步骤都这样做,那么就有O(n^2)。有了几千个元素,你就会开始注意到其中的差异

您不需要
创建列表
,它不创建列表,而是创建字符串,因为Scheme有
生成字符串
,可以满足您的需要:

(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
。有时你没有选择的余地,例如,如果你要复制一个列表,那么通常你可以建立一个反向,然后反向结果。有时您需要使用内存并需要继续,但这将限制在程序停止工作之前,您的结构可以有多深。在rackets的情况下,它不会停止,直到您耗尽了提供给它的整个堆内存

所有方案列表都是从头到尾创建的。您需要先创建
(“XXXX”)
,然后创建
(“XXX”“XXXX”)
等。无论何时创建
(cons“X”(递归…))
,然后
(递归…
都需要在
cons
之前完成,而最有效的方法是使用累加器。使用
append
每个步骤都有错误的味道,因为
append
是O(n),所以如果每个步骤都这样做,那么就有O(n^2)。有了几千个元素,你就会开始注意到其中的差异

您不需要
创建列表
,它不创建列表,而是创建字符串,因为Scheme有
生成字符串
,可以满足您的需要:

(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
。有时你没有选择的余地,例如,如果你要复制一个列表,那么通常你可以建立一个反向,然后反向结果。有时您需要使用内存并需要继续,但这将限制在程序停止工作之前,您的结构可以有多深。在rackets的情况下,它不会停止,直到您耗尽了提供给它的整个堆内存

对。我真的错过了。我错过了