如何将 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-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)
比我们合并 employee-2-v2
到 employee-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))
|#
我刚开始学习 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-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)
比我们合并 employee-2-v2
到 employee-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))
|#