Перестроить список в список средних арифм. элементов - Lisp
Формулировка задачи:
Дан список чисел а1....an. Получить список чисел b1…bn, где bi – среднее арифметическое всех членов последовательности a1….an, кроме ai.Сделать нужно рекурсией.
Что получилось сделать:
но вызвать функцию для того чтобы посчитать просто сумму всех элементов не получилось.
Так же непонятно следующее:
Как получать текущий элемент и отнимать его от суммы в цикле?
(DEFUN SUM (L)
(DO ( (S 0) )
( (NULL L) (setq K S))
(SETQ S (+ S ( CAR L) ) L (CDR L) ) ) )
(DEFUN F(L1 L2)
(COND ((NULL L1)L2)
(T(SUM(L1)F(CDR L1)(CONS(CAR L1)L2)))))Решение задачи: «Перестроить список в список средних арифм. элементов»
textual
Листинг программы
;; racket-lang.org (define (foo lst) (let ((len (sub1 (length lst))) (sum (apply + lst))) (map (lambda (i) (exact->inexact (/ (- sum i) len))) lst))) (foo '(1 2 3 4 5 6)) ; '(4.0 3.8 3.6 3.4 3.2 3.0)
Объяснение кода листинга программы
В данном коде:
foo- название функции, которая принимает один аргументlst- список чисел.lst- список чисел, который передается в функциюfoo.len- переменная, которая содержит длину спискаlst.sum- переменная, которая содержит сумму всех чисел из спискаlst.map- функция, которая применяет к каждому элементу спискаlstуказанную анонимную функцию.- Анонимная функция
(lambda (i) (exact->inexact (/ (- sum i) len))- вычисляет среднее арифметическое каждого элемента спискаlst. - Результатом работы функции
fooявляется новый список средних арифметических значений элементов исходного спискаlst. Код работает следующим образом: - Инициализируются переменные
lenиsumсо значениями длины списка и суммы его элементов соответственно. - С помощью функции
mapкаждый элемент спискаlstпоследовательно обрабатывается анонимной функцией, которая вычисляет среднее арифметическое и сохраняет результат в новый список. - Результат работы функции
fooвыводится на экран. Для списка'(1 2 3 4 5 6)результатом работы функции будет список средних арифметических значений'(4.0 3.8 3.6 3.4 3.2 3.0).