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

Scheme 如何将方案x中的列表复制多次?,scheme,racket,Scheme,Racket,我刚开始学习Scheme,使用cons对我来说有点困惑。我有一个函数duplicate(s number),其中s是一个列表,number是该列表应复制的次数 如果我输入(duplicate'(12)3),输出应该是((12)(12)(12)(12)) 我的程序看起来像这样,但当我运行它时,输出中没有任何内容 (define (duplicate s number) (cond [(null? s) '()] [(> 0 number) (cons (list s) (

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

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

我的程序看起来像这样,但当我运行它时,输出中没有任何内容

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

我做错了什么?

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

您可以通过使用最小样本来构建代码,而不是添加更复杂的数据

如果输入是
(重复x 0)
我们希望输出是
”()

如果输入是
(重复x 1)
我们希望输出是
'(x)

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

(define (duplicate x n)
  (cond
    [(= n 0) '()]
    [else
     (cons x ...)]))
但我们已经知道我们想要的输出是
(x)
,这是
(cons x'())
。 明显的
”()
(重复x 0)
的输出。所以我们在第二个条件中添加
(重复的x(-n1))

#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))
或者你可以这样想。 我们让员工帮我们复印文件

员工1:我们给他一个数字,比他减去1,然后命令员工2完成他的工作

员工2:他复制一份文档,然后向员工3发送消息

员工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-1
合并为
employee-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)
(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)
然后我们将
employee-2-v2
合并到
employee-3-v2
。请记住,我们必须更改输入参数

; (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)
(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)
现在,我们希望删除不必要的输入参数
结果

(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))
|#

s
已经是一个列表。例如,
(12)
(列表s)
将使其成为
((12))
数字为零时,您也应该停止,但当列表为空时,您停止,而不必更改列表。@Sylwester您建议我如何正确停止程序?好的。我确实是在我的评论中当
number
zero?
时写的。想象一下
(复制(12)0)
应该做什么。然后想象一下
(replicate'(12)2);=>(cons'(12)(duplicate'(12)1)
。而且
s
是什么也不重要。例如
(duplicate#f3);==>(#f#f)