如何将 Scheme 中的列表复制 x 次?

How to duplicate a list in Scheme x times?

我刚开始学习 Scheme,使用 cons 对我来说有点混乱。我有一个函数 duplicate (s number),其中 s 是一个列表,number 是列表应该被复制的次数。

如果我输入(duplicate '(1 2) 3),输出应该是((1 2) (1 2) (1 2))

我的程序看起来是这样的,但是当我运行它时,输出中什么也没有

(define (duplicate s number)
  (cond [(null? s) '()]
        [(> 0 number) (cons (list s) (duplicate s(- number 1)))] 
))

我做错了什么?

我们希望第二个输入 n 成为零完成所有列表。 我们希望输出是一个列表,所以我们使用 cons.

与添加更复杂的数据相比,您可以使用最少的样本构建代码。

如果输入是 (duplicate x 0) 我们希望输出是 '().

如果输入是 (duplicate x 1) 我们希望输出是 '(x).

所以你的代码应该是这样的

(define (duplicate x n)
  (cond
    [(= n 0) '()]
    [else
     (cons x ...)]))

但我们已经知道我们想要的输出是 '(x)(cons x '())。 很明显 '()(duplicate x 0) 的输出。所以我们在第二个条件中添加(duplicate x (- n 1))

#lang racket

(define (duplicate x n)
  (cond
    [(= n 0) '()]
    [else
     (cons x (duplicate x (- n 1)))]))


;;; TEST
(duplicate '() 0)
(duplicate '() 3)
(duplicate '() 5) ; '(() () () () ())
(duplicate '(1 2) 5) ; '((1 2) (1 2) (1 2) (1 2) (1 2))

或者你可以这样想。 我们有员工帮我们复印文件。

employee-1 : 我们给他一个数字比他减 1 比命令 employee-2 做他的工作

employee-2 : 他复制一份文件然后给employee-3发消息

employee-3 : 他监督完成与否(数字变为零)。如果未完成,请向员工 1 发送消息。

所以我们想要这样的东西 结束? -> 否 -> 负 1 -> 复制 -> 完成? -> 否 -> 负 1 -> ...

#lang racket

(define x 1)
(define result '())

(define (employee-1 n)
  (employee-2 (- n 1)))

(define (employee-2 n)
  (begin
    (set! result (cons x result))
    (employee-3 n)))

(define (employee-3 n)
  (if (= n 0)
      result
      (employee-1 n)))

;;; TEST
(employee-3 3) ; '(1 1 1)

比我们合并 employee-1employee-3

(define x 1)
(define result '())
; (define (employee-1 n) (employee-2 (- n 1)))

(define (employee-2 n)
  (begin
    (set! result (cons x result))
    (employee-3-v2 n)))

(define (employee-3-v2 n)
  (if (= n 0)
      result
      (employee-2 (- n 1))))

;;; TEST
(employee-3-v2 3) ; '(1 1 1)

我们使用函数输入代替定义全局变量。所以我们必须删除 set! 并更改输入参数。

; (define x 1)
; (define result '())
; (define (employee-1 n) (employee-2 (- n 1)))

(define (employee-2-v2 n x result)
  (employee-3-v2 n x (cons x result)))

(define (employee-3-v2 n x result)
  (if (= n 0)
      result
      (employee-2-v2 (- n 1) x result)))

;;; TEST
(employee-3-v2 3 1 '()) ; '(1 1 1)

比我们合并 employee-2-v2employee-3-v2。请记住,我们必须更改输入参数。

(define (employee-3-v3 n x result)
  (if (= n 0)
      result
      (employee-3-v3 (- n 1) x (cons x result))))

;;; TEST
(employee-3-v3 3 'x '()) ; '(x x x)

现在我们要删除不需要的输入参数result

(define (employee-3-v4 n x)
  (if (= n 0)
      '()
      (cons x (employee-3-v4 (- n 1) x))))

;;; TEST
(build-list 10 (λ (n) (employee-3-v4 n 'x)))

#|
output:

'(()
  (x)
  (x x)
  (x x x)
  (x x x x)
  (x x x x x)
  (x x x x x x)
  (x x x x x x x)
  (x x x x x x x x)
  (x x x x x x x x x))
|#