#scheme #racket
#схема #ракетка
Вопрос:
Я только начинаю изучать схему, и использование 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)))]
))
Что я здесь делаю не так?
Комментарии:
1.
s
это уже список. например.(1 2)
,(list s)
сделает это((1 2))
также, вы должны остановиться, когдаnumber
равно нулю, но вы останавливаетесь, когда список пуст, даже не меняя список.2. @Sylwester Как вы предлагаете мне тогда правильно остановить программу?
3. Хорошо. Я написал, когда
number
zero?
в моем комментарии. Представьте, что(duplicate '(1 2) 0)
должно делать. Тогда представьте это(duplicate '(1 2) 2) ; ==> (cons '(1 2) (duplicate '(1 2) 1)
. Также не имеет значения, чтоs
такое. например.(duplicate #f 3) ;==> (#f #f #f)
Ответ №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))
Или вы можете думать так.
У нас есть сотрудник, который помогает нам копировать документ.
сотрудник-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)
Чем мы объединяем 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))
|#