Как дублировать список в схеме x раз?

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