умножение списка элементов на определенное число «x»

Как бы вы написали процедуру, которая умножает каждый элемент списка на заданное число (x). Если я даю список '(1 2 3) и x = 3, процедура должна вернуть (3 6 9)

Моя попытка:

(define (mul-list list x)
(if (null? list)
1
(list(* x (car list))(mul-list (cdr list)))))

Приведенный выше код не работает. Какие изменения мне нужно внести? Пожалуйста помоги

Заранее спасибо.


person mike    schedule 02.10.2016    source источник


Ответы (2)


Это пример учебника, где вы должны использовать map вместо того, чтобы изобретать велосипед:

(define (mul-list lst x)
  (map (lambda (n) (* x n)) lst))

Но я предполагаю, что вы хотите реализовать его с нуля. Ваш код имеет следующие проблемы:

  • Вы не должны называть list параметром, который конфликтует со встроенной процедурой с тем же именем, которую вы сейчас пытаетесь использовать!
  • Базовый вариант должен возвращать пустой список, учитывая, что мы строим список в качестве вывода.
  • Мы строим списки, cons добавляя элементы, а не вызывая list
  • Вы забыли передать второй параметр рекурсивному вызову mul-list

Это должно исправить все ошибки:

(define (mul-list lst x)
  (if (null? lst)
      '()
      (cons (* x (car lst))
            (mul-list (cdr lst) x))))

В любом случае, он работает так, как ожидалось:

(mul-list '(1 2 3) 3)
=> '(3 6 9)
person Óscar López    schedule 02.10.2016
comment
Большое спасибо! Не могли бы вы порекомендовать мне книгу для начинающих для изучения схемы :) - person mike; 03.10.2016
comment
@mike конечно, с удовольствием :) . «Маленький интриган» и «Как проектировать программы» просто фантастические, а «Структура и интерпретация компьютерных программ» — одна из лучших когда-либо написанных книг по программированию, хотя она и немного более продвинутая. - person Óscar López; 03.10.2016
comment
Большое спасибо :) Оскар Лопес. Это был хороший список - person mike; 03.10.2016
comment
@ ÓscarLópez Я собирался расширить ваш ответ, рассказав о хвостовой рекурсии и предложив альтернативный способ написания процедуры map ... Но чем больше я узнаю о стеке ракетки, тем менее это кажется важным. Как вы думаете, было бы полезно для меня представить эту тему и продемонстрировать некоторые обходные пути? Я спрашиваю именно вас, потому что не хочу тратить время других экспертов (таких как вы), потенциально мутя воду вещами, которые я, возможно, понимаю не так хорошо, как вы. - person Mulan; 03.10.2016
comment
@naomik Было бы нормально показать хвостовую рекурсивную версию, но имейте в виду, что OP все еще учится, и это может быть для него сложной темой;) Кроме того, map обычно реализуется не хвостовым рекурсивным способом. - person Óscar López; 03.10.2016

For и его расширения (for*, for/list, for/first, for/last, for/sum, for/product, for/and, for/or и т. д.: https://docs.racket-lang.org/reference/for.html) очень полезны для циклов в Racket:

(define (ml2 lst x)
  (for/list ((item lst))
    (* item x)))

Тестирование:

(ml2 '(1 2 3) 3)

Выход:

'(3 6 9)

Я обнаружил, что во многих случаях реализация for дает короткий, простой и понятный код.

person rnso    schedule 04.10.2016